1

我正在为硬件安装(水循环系统)构建控制系统。我把它设计成两层:硬件描述层和控制层。

+----------------------------------------------+
|    Control (enables manipulation of devices) |
+----------------------------------------------+
        | uses (decorates)
        v
+---------------------------------------+  (de)serialize  +------------+
|            HW Description             |<--------------->| Files / DB |
| (stores physical layout, cabling etc) |                 +------------+
+---------------------------------------+

硬件描述层包含硬件图,描述管道如何连接到热交换器和其他设备。该层的数据可根据安装进行配置,并将在运行时读取。因此,硬件描述层中的所有类都应该以一种或另一种方式序列化(通过 Hibernate/序列化到 XML 左右)。

控制层将用智能装饰硬件描述层类,因此热交换器将获得一个与之关联的 HeatExchangerController。

在这个系统中,控制层中的实体可能需要通过硬件描述来寻找他们最近的邻居,所以热交换控制器可能会做类似的事情

HeatExchangerController neighbour = this.getHeatExchanger().getInputPipe().getOtherSide().getHeatExchanger().getController();
neighbour.notify(highLoadAlert);

问题是这使得较低层(硬件层)意识到它上面的智能(它的控制器)。这不仅打破了层之间的单向依赖规则,而且由于所有硬件描述类都应该是可序列化的,这使代码复杂化,因为对更高层的所有引用都需要是可选的,声明为瞬态的等。

现在,我有点难以确定通过这样的硬件描述层提供控件是一个好主意还是坏主意,或者是否有任何替代方法可以采用。我只能想到一种方法,它涉及镜像和委托几乎所有的硬件描述层,这似乎是一种很好的侵入方式。

所以我的问题是你们中是否有人认识到这种情况并有任何提示/经验。它有名字吗?是否有任何好的模式/最佳实践,是否有任何其他知名的库/框架也有并解决了这种情况?

谢谢你。

4

4 回答 4

0

采取领域驱动的方法。

如果您也垂直破坏系统(域)。然后这些垂直组件可以通过控制器相互通信,仅此而已。保持每个域内的水平层,域内的分层是垂直的,并且每个域彼此隔离,因为它们只能通过控制器进行通信。

于 2010-09-06T12:33:37.987 回答
0

不太确定你的问题是什么。如果您不想在硬件类中使用 getController() 方法,则可以将硬件->控制器映射存储在弱哈希映射中

public class Controller

    static WeakHashMap<Hardware,Controller> map = ...

    static public Controller of(Hardware hw){ return map.get(hw); }

    Controller(Hardware hw)
    {
        map.put(hw, this);
    }

很多时候,人们喜欢添加“方便”的方法,而不用担心依赖关系的复杂性

user.getThis()
user.getThat()
user.getTheOthers()

虽然User类是一个核心类,但它不应该知道 This, That 和 The Others。现在很多代码都依赖于 User 类,而 User 类又依赖于很多其他的类。最终结果是应用程序中的每个类都依赖于其他所有类,一团糟。

于 2010-09-06T17:18:43.993 回答
0

您还没有向我们展示将控制器逻辑与硬件描述分开会带来什么好处。你确定这种分离值得付出努力吗?

听起来您正在构建贫血域模型

于 2010-09-06T17:49:59.637 回答
0

这是我想到的复杂解决方案。它在硬件层之上添加了一个装饰层,它将控制层的链接添加到每个硬件对象:

                                                                 -+
+--------------------------+               +-----------------+    | 
| HeatExchangerController  |               | PipeController  |     > Controller Layer
+--------------------------+               +-----------------+    |
            ^ 1 controller                        ^ 1 controller -+
            |                                     |
            v 1 heatExchanger                     v 1 pipe       -+
+---------------------------+  inputPipe 1 +------------------+   |
| ControlAwareHeatExchanger |--------------| ControlAwarePipe |    > Decorated HW Layer
+---------------------------+ 1 otherSide  +------------------+   |
            |                                     |              -+
            v 1 realExchanger                     v 1 realPipe   -+
+---------------------------+  inputPipe 1 +------------+         |
|      HeatExchanger        |--------------| Pipe       |          > HW Layer
+---------------------------+ 1 otherSide  +------------+         |
                                                                 -+

装饰层将包含如下代码:

class ControlAwareHeatExchanger {
  private final HeatExchanger realExchanger;
  private final ControlAwarepipe inputPipe;

  public ControlAwareHeatExchanger(HeatExchanger decoratee) {
    realExchanger = decoratee;
    inputPipe = new ControlAwarePipe(decoratee.getInputPipe());
  }

  public ControlAwarePipe getInputPipe() {
    return inputPipe;
  }

  ...
}      

这样你就可以做到:

ControlAwareHeatExchanger controlHE = heatExchangerController.getHeatExchanger();
ControlAwarePipe controlInputPipe = controlHE.getInputPipe();
ControlAwareHeatExchanger otherHE = controlInputPipe.getOtherSide();
HeatExchangerController otherController = otherHE.getController();

所以你可以下到装饰的硬件层,跳来跳去,然后再回到控制器层,这一切都不需要硬件层知道控制层。

但正如您所看到的,您需要镜像所有连接并装饰整个硬件层来实现这一点。会涉及很多代表团。想法?

于 2010-09-07T09:39:30.637 回答