我正在为硬件安装(水循环系统)构建一个控制系统。我把它设计成两层:硬件描述层和控制层。
+----------------------------------------------+
| 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);
问题是这使得下层(硬件层)意识到它上面的智能(其控制器)。这不仅打破了层之间的单向依赖规则,而且由于所有硬件描述类都应该是可序列化的,这使代码变得复杂,因为对更高层的所有引用都需要是可选的,声明为瞬态等。
现在我有点陷入困境,试图通过像这样的硬件描述层使控件可用,或者是否有任何其他方法可以决定是否是好主意。我只能想到一种方法,它涉及镜像和委派几乎所有的硬件描述层,这似乎是侵入性的好方法。
所以我的问题是,如果你们中任何人都认识到这种情况并且有任何提示/经验。它有名字吗?它是否有任何良好的模式/最佳实践,是否还有其他知名的图书馆/框架也曾经解决过这种情况?
谢谢。
答案 0 :(得分:0)
采用域驱动的方法。
如果您也垂直打破系统(域)。然后,这些垂直组件可以通过控制器相互通信,而不是其他任何东西。保持每个域内的水平层,并且分层在域内是垂直的,并且每个域彼此隔离,因为它们只能通过控制器进行通信。
答案 1 :(得分: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。现在,lof代码依赖于User类,而User类依赖于许多其他类。最终结果是应用程序中的每个类都依赖于其他所有类,这是一个混乱的大球。
答案 2 :(得分:0)
您没有向我们展示从硬件描述中分离控制器逻辑可以获得什么好处。你确定这种分离是值得的吗?
听起来你正在构建Anemic Domain Model?
答案 3 :(得分:0)
这是我想到的复杂解决方案。它在HW层的顶部添加了一个装饰层,它将控制层的链接添加到每个HW对象:
-+
+--------------------------+ +-----------------+ |
| 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();
因此,你可以下到装饰的hw层,跳转,然后再次返回控制器层,所有这些都没有hw层知道控制层。
但是正如您所看到的,您需要镜像所有连接并装饰整个HW层以实现此目的。很多代表团都会参与其中。想法?