Let’s say you have
- class Car with Car->tune() and Car->drive()
- class CarDriver
- class CarMechanic
Each CarDriver and CarMechanic object has a reference/pointer to a Car object.
The CarDriver object will call $this->car->drive(), the CarMechanic object will call $this->car->tune().
The question is, how can I prevent a CarDriver from calling $car->tune() ?
There are probably two approaches:
- Language level: Using access modifiers like public/private/protected, and then either abuse inheritance or use more exotic language features like a C++ “friend class”.
- Composition: Split the car into a CarFrontend and CarBackend, or create a DriverCarWrapper, which exposes only the drive() method.
This seems like a good idea, but it will likely introduce clutter and code duplication, which might outweigh the benefits of access control. Especially if there are many methods that should be accessible to the car driver.
Are there any other solutions that I missed?
Background: My real-world use case is in PHP, but I am asking this as a cross-language question.
What you want to do sounds like Double Dispatch.
Basically, you want to dispatch the call to the Car class based on whether the object interacting with the Car is a CarDriver or CarMechanic.
One popular way of implementing this in object oriented languages is with the Visitor pattern.
In your case, you would create DriverVisitor and MechanicVisitor classes that the Driver and Mechanic classes call respectively. These visitors would in turn invoke the appropriate methods on the Car class that are allowable for the Driver and Mechanic roles.
5