Here is the code that violates the open-closed principle:
public Node? Run(Node node)
{
if (node.NodeType == Enum.NodeTypeEnum.ManualTask)
{
// do something
return node.NextNodes.FirstOrDefault();
}
else if (node.NodeType == Enum.NodeTypeEnum.ScriptTask)
{
// do something
return node.NextNodes.FirstOrDefault();
}
else if (node.NodeType == Enum.NodeTypeEnum.ExclusiveGateway)
{
// do something
return node.NextNodes.FirstOrDefault();
}
}
Node entity:
public class Node: EntityBase
{
public NodeTypeEnum NodeType { get; set; }
public List<Node>? NextNodes { get; set; }
public string? NodeCondition { get; set; }
public int ScriptId { get; set; }
}
In the code, we have a node entity which has many types. For each types, we should do some specific operation.
I try to refactor the method as follows:
NodeRunner.cs file:
public class NodeRunner: INodeRunner
{
public virtual bool IsMatch(NodeEntity node)
{
throw new NotImplementedException();
}
public virtual Node Run(NodeEntity node)
{
throw new NotImplementedException();
}
}
ManualTask class:
public class ManualTask : NodeRunner
{
public override bool IsMatch(NodeEntity node)
{
return node.NodeType == NodeType.Manual;
}
public override Node Run(NodeEntity node)
{
return node.NextNodes.FirstOrDefault();
}
}
ScriptTask class:
public class ScriptTask : NodeRunner
{
// ...
public override bool IsMatch(NodeEntity node)
{
return node.NodeType == NodeType.Script;
}
public override Node Run(NodeEntity node)
{
_scriptService.Execute(node.ScriptId);
return node.NextNodes.FirstOrDefault();
}
}
ExclusiveGateway.cs:
public class ExclusiveGateway: NodeRunner
{
public override bool IsMatch(NodeEntity node)
{
return node.NodeType == NodeType.ExclusiveGateway;
}
public override Node Run(Node node)
{
if (node.NextNodes != null)
{
foreach (var nextNode in node.NextNodes)
{
if (_evaluateGatwayCondition.Evaluate(nextNode.NodeCondition, ""))
{
return nextNode;
}
}
}
return new Node();
}
}
And the ProcessService.cs:
public class ProcessService : IProcessService
{
private readonly List<NodeRunner> NodeBrances;
public ProcessService()
{
NodeBrances = new List<NodeRunner>
{
new ManualTask(),
new ScriptTask(),
new ExclusiveGateway()
};
}
public Node Run(Node node)
{
return NodeBrances.First(nb => nb.IsMatch(node)).Run(node);
}
}
ExclusiveGateway does not work and throws a NotImplementedException()
.
What should I do?
Aucun commentaire:
Enregistrer un commentaire