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

发布于 2024-08-16 14:48:50 字数 3312 浏览 1 评论 0原文

我需要帮助重构以下类,

以下是一个在 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);

参考线程:
链接
链接
..还有更多。

i needed help refactoring the following class,

Following is a class Operation with variety of Operations in switch :
i want to avoid the switch statement.I read few articles on using polymorphism and state pattern .but when i refactor the classes i dont get access to many variables,properties
Im confused on whether to use operation as abstract class or to implement an interface.
Just wanted to know which type of refactoring will help in this case
polymorphism or state pattern?
And when to use them?

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....

Calling code is similar to :

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

References Threads:
Link
Link
..many more.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

不喜欢何必死缠烂打 2024-08-23 14:48:51

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

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

I'd like you to check if this switch case is likely to be spawn at multiple places. If it is just isolated to one place, you may choose to live with this. (The alternatives are more complex).

However if you do need to make the change,
Visit the following link - http://refactoring.com/catalog/index.html
Search for "Replace Type Code", there are 3 possible refactorings that you could use. IMHO the Strategy one is the one that you need.

嘴硬脾气大 2024-08-23 14:48:50

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

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

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

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

If you're looking for patterns then I think you should check out the Strategy Pattern and the Chain of Responsiblity Pattern.

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

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

Both of these might be useful ways of thinking about this code.

过度放纵 2024-08-23 14:48:50

在 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 传递给函数状态更新。

In C# you can use functions for the strategy, and using an extension method as the function gives you the ability to add operations as and when required:

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

You could also pass the OperationEvent to the function if you want intermediate status updates.

一曲爱恨情仇 2024-08-23 14:48:50

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

我将创建一个操作接口以及一个保存状态的操作库。

I think you're on the right track in attempting to use polymorphism here. This should lead you to the Strategy pattern.
Refactor the specific operations into subclasses (AddOperation, etc), but also (and this is the step you're probably missing), factor the data (filename, etc), out into a separate object that gets passed to each operation.

I'd create both an Operation interface, as well as an OperationBase that would hold the status.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文