如何避免长时间切换..需要帮助重构

时间:2009-12-23 12:21:10

标签: design-patterns polymorphism switch-statement state refactoring

我需要帮助重构以下类,

以下是交换机中具有各种操作的类操作: 我想避免使用switch语句。我读了几篇关于使用多态和状态模式的文章。但是当我重构类时,我无法访问许多变量,属性
我对是否将操作用作抽象类或实现接口感到困惑 只是想知道在这种情况下哪种类型的重构会有所帮助 多态性或状态模式?
什么时候使用它们?

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

参考文献主题:
Link
Link
..更多。

4 个答案:

答案 0 :(得分:4)

如果您正在寻找模式,那么我认为您应该查看策略模式和责任链模式。

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

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

这两种方法都可能是思考此代码的有用方法。

答案 1 :(得分: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传递给该函数。

答案 2 :(得分:1)

我认为你在这里试图使用多态性是正确的。这应该会引导您进入Strategy模式。 将特定操作重构为子类(AddOperation等),但也(这是您可能缺少的步骤),将数据(文件名等)分解为一个单独的对象传递到每个操作。

我创建了一个Operation接口,以及一个保持状态的OperationBase。

答案 3 :(得分:0)

我希望你检查这个开关盒是否可能在多个地方产生。如果它只是隔离到一个地方,你可以选择住这个。 (替代方案更复杂)。

但是,如果您确实需要进行更改, 请访问以下链接 - http://refactoring.com/catalog/index.html
搜索“替换类型代码”,您可以使用3种可能的重构。恕我直言,战略一是你需要的。