1

ハードウェア設置用の制御システム(水循環システム)を構築しています。ハードウェア記述層と制御層の2つの層で設計しました。

+----------------------------------------------+
|    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);

問題は、これにより、下位層(ハードウェア層)がその上位のインテリジェンス(そのコントローラー)を認識できるようになることです。これは、レイヤー間の一方向の依存関係ルールを破るだけでなく、すべてのハードウェア記述クラスをシリアライズ可能にする必要があるため、上位レイヤーへのすべての参照はオプションである必要があり、一時的であると宣言される必要があるため、コードが複雑になります。

このようにHW記述レイヤーを介してコントロールを使用できるようにするのが良いか悪いか、または別の方法があるかどうかを判断しようとすると、少し行き詰まります。私は、HW記述レイヤーのほとんどすべてをミラーリングして委任することを含む、1つの方法しか考えられません。これは、邪魔になる方法のようです。

ですから、私の質問は、この状況を認識し、ヒントや経験を持っている人がいるかどうかです。名前はありますか?そのための良いパターン/ベストプラクティスはありますか?また、この状況を回避して回避した他の有名なライブラリ/フレームワークはありますか?

ありがとうございました。

4

4 に答える 4

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  +------------+         |
                                                                 -+

Decorated レイヤーには、次のようなコードが含まれます。

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 レイヤー全体を装飾する必要があります。多くの代表団が参加します。考え?

于 2010-09-07T09:39:30.637 に答える
0

ドメイン駆動型のアプローチを取る。

システムを縦(ドメイン)に分割する場合も同様です。次に、これらの垂直コンポーネントは、コントローラーを介して互いに通信できますが、他には何もありません。各ドメイン内で水平レイヤーを維持し、レイヤーはドメイン内で垂直になり、各ドメインはコントローラーを介してのみ通信できるため、互いに分離されます。

于 2010-09-06T12:33:37.987 に答える
0

コントローラーのロジックをハードウェアの説明から分離することで得られる利点をまだ示していません。この分離は努力する価値があると確信していますか?

貧血ドメイン モデルを構築しているようですね。

于 2010-09-06T17:49:59.637 に答える
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、これ、あれ、その他の知識を持つべきではありません。現在、多くのコードが User クラスに依存しており、User クラスは他の多くのクラスに依存しています。その結果、アプリケーション内のすべてのクラスが他のすべてのクラスに依存することになり、大きな混乱が生じます。

于 2010-09-06T17:18:43.993 に答える