2

現在のプロジェクトの大規模なチェックアウト アプリケーションに取り組んでいます。このチェックアウトには、ユーザーの管理者レベル、チェックアウトに到達した方法、およびチェックアウトするアイテムの種類に応じて多くのケースがあるため、プロセスは一連のコンテキスト クラスを介して .aspx ページから抽象化されます。

これらのクラスはすべて、1 つのクラス CheckoutContext のサブクラスであり、使用されるクラスのタイプは列挙型によって示されます。

使用するサブクラスを選択するために使用できる typedef に似たものはありますか、または次のように、関連するクラスを返すメソッドを単に持つ必要があります。

CheckoutContext chooseSubclass(CheckoutCase c)
{
CheckoutContext output;
switch (c):
{
  case CheckoutCase.SingleItemNew:
    output = new SingleItemNew;
    break;
  case . . . 
  return output;
}
}

4

5 に答える 5

4

実装しているのはFactory Patternです。これは標準的な方法ですが、通常は多くの反復的なコードを記述することを意味します (switch ステートメントのように、多くの場合、実装方法です)。リフレクションによる動的なインスタンス化など、あらゆる種類の派手なことを行うことができますが、火遊びはしないでください。switch ステートメントに固執するだけで問題ありません。

于 2009-06-10T15:27:15.237 に答える
1

ケースが多数ある場合は、 を作成し、Dictionary<CheckoutCase, Type>すべての CheckoutCase 値と対応する CheckoutContext タイプのセットを 1 回入力します。次に、Activator.CreateInstance を使用して、巨大な switch ステートメントの代わりに適切な型を返すことができます。

于 2009-06-10T15:35:40.383 に答える
0

CheckoutContext の型となる 1 つのプロパティを持つ属性を作成できます。

public class CheckoutContextAttribute : Attribute
{
   public Type CheckoutType{get;set;}
}

次に、列挙型で、正しい列挙型に正しい属性を配置できます。

public enum CheckoutCase
{
   [CheckoutContext(CheckoutType=typeof(SingleItemNew)]
   SingleItemNew,
   ...
   ...
}

次に、正しい Context タイプを送り返す必要があるメソッドで、リフレクションを使用して次のようにします。

public CheckoutContext GetContext(CheckoutCase c)
{
   FieldInfo field = c.GetType().GetField(c.ToString());
   object[] attribs = field.GetCustomAttributes(typeof(CheckoutContextAttribute),false);
   CheckountContext result = null;
   if(attribs.Length > 0)
   {
      CheckoutContextAttribute attrib = attribs[0] as CheckoutContextAttribute;
      Type type = attrib.CheckoutType;
      result = Activator.CreateInstance(type) as CheckountContext;
   }

   return result;
}

これでうまくいくはずです。安全のために、null /エラーチェックを追加するだけです。

于 2009-06-10T15:51:47.967 に答える
0

これは工場設計パターンと呼ばれます。必要なクラスを返す静的メソッドを作成します。ここでの良い方法は、インターフェイスを実装してインターフェイスを返すことです。

interface ICheckoutItem
{
    void CheckOut();
}

アイテムにインターフェースを実装させます。次に、ファクトリ メソッドで各アイテムのインターフェイスを返します。

ICheckoutItem chooseSubclass(CheckoutCase c)
{
ICheckoutItem output;
    switch (c):
    {
       case CheckoutCase.SingleItemNew:
         output = new SingleItemNew;
         break;
       case . . . 
  return output;
    }
}
于 2009-06-10T15:32:10.533 に答える
0

カスタム属性とファクトリ メソッドを使用してこれを実装できます。すべてのサブクラスに、CheckOutCase Enum 値を取る CheckOutCaseScenarioAttribute などの CustomAttribute を実装させます。

ファクトリ メソッド内で、この Enum 値が設定されている型を探し、オブジェクトを作成します。これにより、スイッチケースが回避されます。これは、ファクトリ メソッド内に他の初期化ロジックがない場合に機能します。

于 2009-06-10T15:31:35.103 に答える