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

发布于 2024-09-15 02:34:33 字数 2706 浏览 5 评论 0原文

简短问题

我有一个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 处理某些网络事件时,它们会被调用(请记住,手臂位于远程位置,因此事件是通过网络接收的)。例如:

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() 等等。

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

问题

我不能 100% 确定这是代理模式还是适配器模式。您认为这是对此类系统进行建模的正确方法吗?有更好的模式吗?

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, 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 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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

软糖 2024-09-22 02:34:33

具有执行相同操作但抽象级别不同的类是很常见的。

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

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

在您的示例中,RoboticArm 已从 RealRoboticArm 中抽象出对事物的持有。 RoboticArm 不是设置和释放东西,而是神奇地知道它是否拿着东西以及它拿着什么。这既不是代理也不是适配器。

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

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.

旧话新听 2024-09-22 02:34:33

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

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

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文