I have one C++ object that models a real-world object in a remote system. Whenever something happens in the real-world object, the model changes to reflect it. In the same way, the model lets you interact with the real object and make it to perform several actions. It has some methods used by the internal API as well as other public methods. I don’t want to expose those API methods. I’m thinking of using the proxy pattern to hide those methods. Do you think this is a good idea? Is there some design pattern to achieve this?
As an example: let’s say there’s a robotic arm in some remote location that can be controlled by the software but can also be manually moved by some technician. It has some sensors that allow it to know which kind of object it is holding. In my proyect it’s something completely different but I use this just as an example. So I’d have one RoboticArm class which contains a RoboticHeldObject abstract class. RoboticArm let’s you know which RoboticHeldObject it is holding, appart from letting you move the arm. However, you can’t decide to pickup and release an object. This is decided by a technician operating the robot. So it would be something like:
---------------------------------------------
RoboticArm
---------------------------------------------
+ heldObject() RoboticHeldObject*
+ moveUp()
+ moveDown()
+ setObjectReleased()
+ setObjectHeld(RoboticHeldObject*)
---------------------------------------------
- heldObject RoboticHeldObject*
- service RobotService
Since the implementation is quite complex, I use an external class, RobotService which actually performs the hard work. However, it’s not an Anemic Domain Model since it’s RoboticArm who actually uses RobotService (thus has functionality) and the rest of the world doesn’t know anything about RobotService.
The question here is: setObjectRelased() and setObjectHeld() are API methods here used by RobotService only. They are called only by RobotService whenever a technician releases the object being hold by the arm or places a new object. Thus, they are called when some network event is handled by RobotService (remember the arm is in a remote location, so events are received through a network). For example:
RobotService::handleObjectReleaseEvent(event)
{
RoboticArm *arm = correspondingRoboticArm(event);
arm->setObjectReleased();
}
My approach to hide those methods is to rename RoboticArm to RealRoboticArm and create a RoboticArm proxy class:
---------------------------------------------
RoboticArm (the proxy)
---------------------------------------------
+ heldObject() RoboticHeldObject*
+ moveUp()
+ moveDown()
---------------------------------------------
- realArm RoboticArm*
---------------------------------------------
RealRoboticArm (the real object)
---------------------------------------------
+ heldObject() RoboticHeldObject*
+ moveUp()
+ moveDown()
+ setObjectReleased()
+ setObjectHeld(RoboticHeldObject*)
---------------------------------------------
- heldObject RoboticHeldObject*
- service RobotService
Since RoboticArm is a proxy, RoboticArm::heldObject() would call realArm->heldObject(), RoboticArm::moveUp() realArm->moveUp() and so on.
The RobotService would have a pointer to the RealRoboticArm instance, so it could call the API methods such as setObjectReleased(). However, other parts of the application would only be able to use the methods in RoboticArm, since they don’t have a pointer to RealRoboticArm. Thus setObjectReleased() and setObjectHeld() would be effectively hidden from the audience.
I am not 100% sure if this is the proxy pattern or the adapter pattern.
Do you think this is a proper way to model such system? Is there a better pattern?