1

我需要帮助重构以下类,

以下是在 switch 中具有多种操作的类操作:我想避免使用 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);

参考主题:
链接
链接
..还有更多。

4

4 回答 4

4

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

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 等),而且(这可能是您可能缺少的步骤)将数据(文件名等)分解为一个单独的对象,该对象将传递给每个操作。

我会创建一个操作接口,以及一个保存状态的 OperationBase。

于 2009-12-23T12:28:21.860 回答
0

我想让你检查一下这个开关盒是否可能在多个地方产生。如果它只是孤立在一个地方,你可以选择和它一起生活。(替代方案更复杂)。

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

于 2009-12-23T12:37:51.653 回答