7

次の問題があります。モデルを自動的に (イベントをリッスンして) 制御する一連のエンジンがあります。次の図は、一般的なクラス図を示しています。 クラス図

現在、EngineFacade を認識しているクライアントがあり、クライアントから Engine2 からプロパティ Active を設定したいのですが、クライアントも EngineFacade も 3 つのエンジンのどれが Engine2 であるかを認識していません。

2つの方法がありますが、私はそれらのどれも好きではありません:

  1. エンジンの 1 つがタイプ Engine2 であるかどうかを確認します。同じタスクを実行するが別の名前の別のクラスがある場合は、EngineBuilder と EngineFacade でそれを変更する必要があります。
  2. 識別子文字列で確認してください - 私は魔法の文字列があまり好きではありません。

クライアント サイトで私が知っていることは、グリッドを処理するエンジンがある、またはあるべきだということです。しかし、私はもっと知りません。

たぶん、私は 2 人の悪魔のどちらかを選ばなければならないかもしれませんが、どちらかがより良い解決策を持っているかもしれません。

4

1 に答える 1

1

Engine2次のように、の実装で属性を使用できます。

[AttributeUsage(AttributeTargets.Class)]
public class HandlesGridAttribute : Attribute { }

次に、これを派生に適用します。

[HandlesGrid]
public Engine2 : EngineBase { ... }

次に、クライアントで、属性を確認します。

IEnumerable<EngineBase> bases = ...;

// Get all the implementations which handle the grid.
IEnumerable<EngineBase> handlesGrid = bases.
    Where(b => b.GetType().
        GetCustomAttributes(typeof(HandlesGridAttribute), true).Any());

// Set the active property.
foreach (EngineBase b in handlesGrid) b.Active = true;

ここでの主な欠点(適用される場合と適用されない場合があります)は、実行時に値を変更できないことです(属性はコンパイル時にベイクインされるため)。エンジンがこのように動的でない場合は、属性が正しい方法です。

ただし、派生が実行時にこのアクションを実行できるかどうかを変更する必要がある場合は、2番目のオプションであるエンジンの属性を識別するコード構造にフォールバックする必要があります。文字列である必要はありませんが(私も好きではありません)、探している情報を提供する、より構造化されたものにすることができます。

于 2013-03-08T14:51:58.173 に答える