开发者

Hide to the rest of the world some methods used only by internal classes

开发者 https://www.devze.com 2023-01-12 09:02 出处:网络
Short question I have one C++ domain model. 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 p

Short question

I have one C++ domain model. 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?

Long 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 project it's something completely different, but I'm just using this 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()
+ releaseObject()
+ holdObject(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: releaseObject() and holdObject() 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->releaseObject();
}

My approach

To hide those methods, I would 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()
+ releaseObject()
+ holdObject(RoboticHeldObject*)
---------------------------------------------
- heldObject               RoboticHeldObject*
- service                  RobotService

Since RoboticArm is a proxy, Ro开发者_开发问答boticArm::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 releaseObject(). 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 releaseObject() and holdObject() would be effectively hidden from the audience.

The question

I am not 100% sure if this is the proxy pattern or the adapter pattern. Do you think this is the proper way to model such a system? Is there a better pattern?


It is common to have classes which do the same thing, but on different levels of abstraction.

Example, in decreasing levels of abstraction:

  • GrabbingRobot.GrabBottle();
  • SpaciousRobotArm.MoveToCoordinates(x, y);
  • RobotBase.Turn(degrees), RobotArm.Extend(inches)
  • RobotElbow.Bend(degrees)
  • RobotServoMotor.Turn(cycles)
  • RobotServoRelais.TurnOn(seconds)

In your example, RoboticArm has abstracted the holding of things out of RealRoboticArm. Instead of setting and releasing things, the RoboticArm magically knows whether it is holding something and what it is holding. This is neither Proxy nor Adapter.

There is no sufficient elaborate permissions structure to prevent GrabbingRobot from calling RobotElbow directly.


You can solve your problem using interfaces. You have one object, RobotArm, which implements two interfaces: one for the API and one for the using class.

The using class will use its interface, the one without the API methods, and thus can not call the API methods.

0

精彩评论

暂无评论...
验证码 换一张
取 消