我需要帮助重构以下类,
以下是交换机中具有各种操作的类操作:
我想避免使用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);
答案 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种可能的重构。恕我直言,战略一是你需要的。