向世界其他地方隐藏一些仅由内部类使用的方法

时间:2010-08-22 10:12:55

标签: design-patterns encapsulation proxy-classes

简短问题

我有一个 C ++ 域模型。它有一些内部API以及其他公共方法使用的方法。 我不想公开这些API方法。我正在考虑使用代理模式隐藏这些方法。你认为这是个好主意吗?是否有一些设计模式来实现这一目标?

长示例

假设某个远程位置有一个机器人手臂可由软件控制,但也可由某些技术人员手动移动。它有一些传感器,可以让它知道它所持有的物体类型。在我的项目中,它完全不同,但我只是以此为例。所以我有一个 RoboticArm 类,其中包含一个 RoboticHeldObject 抽象类。 RoboticArm 让你知道它所持有的 RoboticHeldObject ,让你移动手臂。但是,您无法决定拾取和释放对象。这由操作机器人的技术人员决定。所以它会是这样的:

---------------------------------------------
RoboticArm
---------------------------------------------
+ heldObject()             RoboticHeldObject*
+ moveUp()
+ moveDown()
+ releaseObject()
+ holdObject(RoboticHeldObject*)
---------------------------------------------
- heldObject               RoboticHeldObject*
- service                  RobotService

由于实现非常复杂,我使用外部类 RobotService 来实际执行艰苦的工作。但是,它不是一个贫血领域模型,因为它的 RoboticArm 实际使用 RobotService (因此具有功能),而世界其他地方对 RobotService一无所知

这里的问题是: releaseObject() holdObject()是此处仅由 RobotService 使用的API方法。只要技术人员释放手臂所持有的对象或放置新对象,它们就只能由 RobotService 调用。因此,当某些网络事件由 RobotService 处理时,它们会被调用(请记住,arm位于远程位置,因此通过网络接收事件)。例如:

RobotService::handleObjectReleaseEvent(event)
{
 RoboticArm *arm = correspondingRoboticArm(event);
 arm->releaseObject();
}

我的方法

要隐藏这些方法,我会将 RoboticArm 重命名为 RealRoboticArm 并创建 RoboticArm 代理类:

---------------------------------------------
RoboticArm        (the proxy)
---------------------------------------------
+ heldObject()             RoboticHeldObject*
+ moveUp()
+ moveDown()
---------------------------------------------
- realArm                  RoboticArm*



---------------------------------------------
RealRoboticArm    (the real object)
---------------------------------------------
+ heldObject()             RoboticHeldObject*
+ moveUp()
+ moveDown()
+ releaseObject()
+ holdObject(RoboticHeldObject*)
---------------------------------------------
- heldObject               RoboticHeldObject*
- service                  RobotService

由于 RoboticArm 是一个代理,RoboticArm :: heldObject()会调用realArm-> heldObject(),RoboticArm :: moveUp()realArm-> moveUp()等等。 / p>

RobotService 将有一个指向 RealRoboticArm 实例的指针,因此它可以调用API方法,例如releaseObject()。但是,应用程序的其他部分只能使用 RoboticArm 中的方法,因为它们没有指向 RealRoboticArm 的指针。因此, releaseObject() holdObject()将被有效地隐藏在观众之外。

问题

我不是100%确定这是代理模式还是适配器模式。你认为这是建立这样一个系统的正确方法吗?有更好的模式吗?

2 个答案:

答案 0 :(得分:0)

通常有一些类可以做同样的事情,但是在不同的抽象层次上。

示例,在降低抽象级别时:

  • GrabbingRobot.GrabBottle();
  • SpaciousRobotArm.MoveToCoordinates(x,y);
  • RobotBase.Turn(度),RobotArm.Extend(英寸)
  • RobotElbow.Bend(度)
  • RobotServoMotor.Turn(周期)
  • RobotServoRelais.TurnOn(秒)

在你的例子中,RoboticArm抽象出了RealRoboticArm中的东西。 RoboticArm不是设置和释放东西,而是神奇地知道它是拿着什么东西以及它拿着什么。这既不是代理也不是适配器。

没有足够精细的权限结构来阻止GrabbingRobot直接调用RobotElbow。

答案 1 :(得分:0)

您可以使用界面解决问题。你有一个对象RobotArm,它实现了两个接口:一个用于API,另一个用于using类。

using类将使用其接口,没有API方法的接口,因此无法调用API方法。