我需要帮助重构以下课程,
以下是在开关中具有各种操作的类操作:我想避免使用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);
在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
传递给该函数。
如果您正在寻找模式,那么我认为您应该检查一下策略模式和责任链模式。
http://en.wikipedia.org/wiki/Strategy_pattern
http://en.wikipedia.org/wiki/Chain_of_responsibility_pattern
这两种都是思考此代码的有用方法。
我认为您在此处尝试使用多态性的方向正确。这将引导您进入Strategy模式。将特定的操作重构为子类(AddOperation等),但也可以(这可能是您所缺少的步骤),将data(文件名等)分解为一个单独的对象,该对象将传递给每个对象操作。
我将同时创建一个Operation接口和一个将保持状态的OperationBase。
我希望您检查此开关盒是否有可能在多个地方产生。如果它只是一个地方而已,您可以选择住这个地方。 (替代方案更为复杂)。
但是,如果您确实需要进行更改,访问以下链接-http://refactoring.com/catalog/index.html搜索“替换类型代码”,您可以使用3种可能的重构。恕我直言,策略之一就是您需要的策略。