gpt4 book ai didi

c# - 修改后的责任链

转载 作者:太空宇宙 更新时间:2023-11-03 23:40:48 24 4
gpt4 key购买 nike

我非常了解责任链模式的基础知识。但是,我想问一下是否可以动态设置序列中的下一个接收者。

基本思想是根据批准者的先后顺序,实例化下一个对象。

示例如下:

抽象基类

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 类。

有没有办法将其调整为所提到的所需逻辑?如果是这样,它是如何完成的?

最佳答案

如果我理解正确,您需要通过运行时值(在本例中为字符串)配置您的批准者。

只需对您的代码进行很少的更改,这是可能的。这是所需的修改。

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 属性。

关于c# - 修改后的责任链,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29092296/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com