我非常了解责任链模式的基本知识。但是,我想问一下,是否可以动态地设置序列中的下一个接收器。
基本思想是,根据批准者的顺序,它将实例化下一个对象。
下面是一个例子:
抽象基类
public abstract class ApproverCategorizer
{
protected ApproverCategorizer NextApprover { get; private set; }
public ApproverCategorizer RegisterNextApprover(ApproverCategorizer nextApprover)
{
NextApprover = nextApprover;
return nextApprover;
}
public abstract void ApproveAmount(TestEntity entity);
protected bool IsLast(Queue<string> approverQueue)
{
return string.IsNullOrEmpty(approverQueue.Peek());
}
}高级审批人级
public class OfficerAApprover : ApproverCategorizer
{
public override void ApproveAmount(TestEntity entity)
{
entity.ApproverQueue.Dequeue();
if (entity.Amount <= 300)
{
entity.Status = "Approved";
return;
}
if (!IsLast(entity.ApproverQueue) && string.IsNullOrWhiteSpace(entity.Status))
{
NextApprover.ApproveAmount(entity);
return;
}
else
{
entity.Status = "Rejected";
}
}
}军官B级
public class OfficerBApprover : ApproverCategorizer
{
public override void ApproveAmount(TestEntity entity)
{
entity.ApproverQueue.Dequeue();
if (entity.Amount <= 300)
{
entity.Status = "Approved";
return;
}
if (!IsLast(entity.ApproverQueue) && string.IsNullOrWhiteSpace(entity.Status))
{
NextApprover.ApproveAmount(entity);
return;
}
else
{
entity.Status = "Rejected";
}
}
}认可链类
public class ApproverChain
{
public static TestEntity Entity { get; set; }
public static ApproverCategorizer Approver { get; set; }
public ApproverChain()
{
List<string> approverList = Entity.ApproverList.Split(',').ToList();
Queue<string> approverQueue = new Queue<string>();
Approver = new StartApprover();
// Note: The code below is working, but not the desired logic.
//Approver.RegisterNextApprover(new OfficerAApprover()).RegisterNextApprover(new OfficerBApprover());
// Note: This code below is not working, but this is the desired logic.
foreach (string approver in approverList)
{
switch (approver)
{
case "OfficerA":
Approver.RegisterNextApprover(new OfficerAApprover());
break;
case "OfficerB":
Approver.RegisterNextApprover(new OfficerBApprover());
break;
}
approverQueue.Enqueue(approver);
}
Entity.ApproverQueue = approverQueue;
}
public string StartProcess()
{
Approver.ApproveAmount(Entity);
return Entity.Status;
}
}商务类
public string ProcessApproval()
{
TestEntity entity = new TestEntity
{
Amount = 500,
ApproverList = "OfficerB,OfficerA"
};
ApproverChain.Entity = entity;
ApproverChain chain = new ApproverChain();
var result = chain.StartProcess();
return result;
}这意味着OfficerB类将首先处理。如果失败,它将转到OfficerA类。
是否有一种方法可以将其调整为所需的逻辑?如果是的话,是如何做到的?
发布于 2015-03-17 07:11:53
如果我正确理解,您需要通过运行时值(在本例中为string)配置您的审批者。
如果您的代码很少更改,这是可能的。这是所需的修改。
public ApproverChain()
{
List<string> approverList = Entity.ApproverList.Split(',').ToList();
Queue<string> approverQueue = new Queue<string>();
Approver = new StartApprover();
ApproverCategorizer currentApprover = Approver;
foreach (string approver in approverList)
{
switch (approver)
{
case "OfficerA":
currentApprover = currentApprover.RegisterNextApprover(new OfficerAApprover());
break;
case "OfficerB":
currentApprover = currentApprover.RegisterNextApprover(new OfficerBApprover());
break;
}
approverQueue.Enqueue(approver);
}
Entity.ApproverQueue = approverQueue;
}上面的代码会运行得很好。但对我来说,ApproverQueue看起来很可疑。
似乎您使用ApproverQueue属性只是为了了解当前审批者是否是链中的最后一个审批者。您可以通过简单地将NextApprover检查为null并完全消除该approverQueue来找到它。
那么您的代码就变成了
public class ApproverChain
{
public static TestEntity Entity { get; set; }
public static ApproverCategorizer Approver { get; set; }
public ApproverChain()
{
Approver = new StartApprover();
List<string> approverList = Entity.ApproverList.Split(',').ToList();
ApproverCategorizer currentApprover = Approver;
foreach (string approver in approverList)
{
switch (approver)
{
case "OfficerA":
currentApprover = currentApprover.RegisterNextApprover(new OfficerAApprover());
break;
case "OfficerB":
currentApprover = currentApprover.RegisterNextApprover(new OfficerBApprover());
break;
}
}
}
public string StartProcess()
{
Approver.ApproveAmount(Entity);
return Entity.Status;
}
}
public abstract class ApproverCategorizer
{
protected ApproverCategorizer NextApprover { get; private set; }
public ApproverCategorizer RegisterNextApprover(ApproverCategorizer nextApprover)
{
NextApprover = nextApprover;
return nextApprover;
}
public abstract void ApproveAmount(TestEntity entity);
protected bool IsLast()
{
return NextApprover == null;
}
}
public class OfficerAApprover : ApproverCategorizer
{
public override void ApproveAmount(TestEntity entity)
{
if (entity.Amount <= 300)
{
entity.Status = "Approved";
return;
}
if (!IsLast() && string.IsNullOrWhiteSpace(entity.Status))
{
NextApprover.ApproveAmount(entity);
return;
}
else
{
entity.Status = "Rejected";
}
}
}而且您的TestEntity类将不具有ApproverQueue属性。
https://stackoverflow.com/questions/29092296
复制相似问题