1

次のクラスをリファクタリングするのに助けが必要でした。

以下は、スイッチのさまざまな操作を含むクラス操作です。スイッチステートメントを避けたいと思います。ポリモーフィズムと状態パターンの使用に関する記事はほとんど読みませんでした
。操作を抽象クラスとして使用するか、インターフェイスを実装します。
この場合、どのタイプのリファクタリングが
ポリモーフィズムまたは状態パターンに役立つか知りたいですか?
そして、いつそれらを使用するのですか?

public class Operation
    {
        public enum OperationType
        {
            add,
            update,
            delete,
            retrieve
        }
        public enum OperationStatus
        {
            Success,
            NotStarted,
            Error,
            Fail,
            InProcess,
            Free
        }

    // raise this event when operation completes
    public delegate void OperationNotifier(Operation operation);
    public event OperationNotifier OperationEvent=null;           

    private OperationStatus _status=OperationStatus.Free;
    public OperationStatus Status
    {
        get { return _status; }
        set { _status = value; }
    }      


    private string _fileName = null;

    public string FileName
    {
        get { return _fileName; }
        set { _fileName = value; }
    }

    private string _opnid = null;

    public string OperationId
    {
        get { return _opnid; }
        set { _opnid = value; }
    }

    private OperationType _type;
    public OperationType Type
    {
        get { return _type; }
        set { _type = value; }
    }

   public void performOperation(OperationType type, string parameters)
    {  

        switch (type)
        {
            case OperationType.add:
                _status = addOperation(parameters);                   
                break;
            case OperationType.update:
               _status = updateOperation(parameters);
                break;
            case OperationType.delete:
                _status = deleteOperation(parameters);
                break;
            case OperationType.retrieve:
                _status = retrieveOperation(parameters);
                break;
            default:
                break;
        }
        if (OperationEvent != null)
            OperationEvent(this);           
       // return true;
    }


    public OperationStatus addOperation(string parameters)
    {           
        DateTime start = DateTime.Now;
         //Do SOMETHING BIG
        TimeSpan timeTaken = DateTime.Now - start;
        System.Diagnostics.Debug.WriteLine("addOperation:-" + _opnid + "-" + _fileName + "--" + timeTaken.Milliseconds); 
        return OperationStatus.Success;

        }
...other operations here....

呼び出しコードは次のようになります。

  Operation oprnObj;
                Operation.OperationType operationType;

 oprnObj = new Operation();
 oprnObj.FileName = String.Concat("myxmlfile",".xml");
 oprnObj.OperationId = oprnid;
 oprnObj.OperationEvent += new Operation.OperationNotifier(oprnObj_OperationEvent);
 operation="add"; //get From Outside function getOperation()
 operationType = (Operation.OperationType)Enum.Parse(typeof(Operation.OperationType),   operation.ToLower(), true);
 oprnObj.Type = operationType;
 oprnObj.performOperation(operationType, parameters);

参照スレッド:
リンク
リンク
..その他多数。

4

4 に答える 4

4

パターンを探しているなら、Strategy パターンと Chain of Responsiblity パターンを調べるべきだと思います。

http://en.wikipedia.org/wiki/Strategy_pattern

http://en.wikipedia.org/wiki/Chain_of_responsibility_pattern

これらは両方とも、このコードについて考えるのに役立つ方法かもしれません。

于 2009-12-23T12:29:49.423 に答える
2

C# では、戦略に関数を使用できます。関数として拡張メソッドを使用すると、必要に応じて操作を追加できます。

public enum OperationStatus
{
    Success, NotStarted, Error, Fail, InProcess, Free
}

public class Operation
{
    // raise this event when operation completes
    public delegate void OperationNotifier(Operation operation, OperationStatus status);
    public event OperationNotifier OperationEvent = null;

    public string FileName { get; set; }
    public string OperationId { get; set; }

    public Func<string, OperationStatus> Function { get; set; }

    public void PerformOperation(string parameters)
    {
        OperationStatus status = Function(parameters);

        if (OperationEvent != null)
            OperationEvent(this, status);
    }
}

static class AddOp
{
    public static OperationStatus AddOperation(this Operation op, string parameters)
    {
        DateTime start = DateTime.Now;
        //Do SOMETHING BIG
        TimeSpan timeTaken = DateTime.Now - start;
        System.Diagnostics.Debug.WriteLine("addOperation:-" + op.OperationId + "-" + op.FileName + "--" + timeTaken.Milliseconds);
        return OperationStatus.Success;
    }
}

class Program
{
    static void Main(string[] args)
    {
        Operation oprnObj = new Operation();
        oprnObj.FileName = String.Concat("myxmlfile", ".xml");
        oprnObj.OperationId = "oprnid";
        oprnObj.OperationEvent += new Operation.OperationNotifier(oprnObj_OperationEvent);
        string parameters = "fish";
        oprnObj.Function = oprnObj.AddOperation;
        oprnObj.PerformOperation(parameters);
    }

    public static void oprnObj_OperationEvent(Operation op, OperationStatus status)
    {
        Console.WriteLine("{0} returned {1}", op.Function.Method.Name, status);
    }
}

OperationEvent中間ステータスの更新が必要な場合は、 を関数に渡すこともできます。

于 2009-12-23T13:01:17.853 に答える
1

ここでポリモーフィズムを使用しようとしているあなたは正しい方向に進んでいると思います。これにより、戦略パターンにたどり着くはずです。特定の操作をサブクラス (AddOperation など) にリファクタリングするだけでなく (これはおそらく欠落しているステップです)、データ(ファイル名など) を各操作に渡される個別のオブジェクトに分解します。

Operation インターフェイスと、ステータスを保持する OperationBase の両方を作成します。

于 2009-12-23T12:28:21.860 に答える
0

このスイッチ事件が複数箇所で発生する可能性があるかどうかを確認していただきたいです。1 か所に孤立している場合は、これと一緒に暮らすことを選択できます。(代替案はより複雑です)。

ただし、変更を行う必要がある場合は
、次のリンクにアクセスしてください - http://refactoring.com/catalog/index.html
「Replace Type Code」を検索してください。使用できる 3 つのリファクタリングがあります。IMHO the Strategy oneはあなたが必要とするものです。

于 2009-12-23T12:37:51.653 に答える