C#与代表的责任链
出于我的理解目的,我实施了责任链模式C#与代表的责任链,c#,chain-of-responsibility,C#,Chain Of Responsibility,出于我的理解目的,我实施了责任链模式 //Abstract Base Type public abstract class CustomerServiceDesk { protected CustomerServiceDesk _nextHandler; public abstract void ServeCustomers(Customer _customer); public void SetupHadler(CustomerServiceDesk _nextHandler) {
//Abstract Base Type
public abstract class CustomerServiceDesk
{
protected CustomerServiceDesk _nextHandler;
public abstract void ServeCustomers(Customer _customer);
public void SetupHadler(CustomerServiceDesk _nextHandler)
{
this._nextHandler = _nextHandler;
}
}
public class FrontLineServiceDesk:CustomerServiceDesk
{
public override void ServeCustomers(Customer _customer)
{
if (_customer.ComplaintType == ComplaintType.General)
{
Console.WriteLine(_customer.Name + " Complaints are registered ;
will be served soon by FrontLine Help Desk..");
}
else
{
Console.WriteLine(_customer.Name + "
is redirected to Critical Help Desk");
_nextHandler.ServeCustomers(_customer);
}
}
}
public class CriticalIssueServiceDesk:CustomerServiceDesk
{
public override void ServeCustomers(Customer _customer)
{
if (_customer.ComplaintType == ComplaintType.Critical)
{
Console.WriteLine(_customer.Name +
"Complaints are registered ; will be served soon
by Critical Help Desk");
}
else if (_customer.ComplaintType == ComplaintType.Legal)
{
Console.WriteLine(_customer.Name +
"is redirected to Legal Help Desk");
_nextHandler.ServeCustomers(_customer);
}
}
}
public class LegalissueServiceDesk :CustomerServiceDesk
{
public override void ServeCustomers(Customer _customer)
{
if (_customer.ComplaintType == ComplaintType.Legal)
{
Console.WriteLine(_customer.Name +
"Complaints are registered ;
will be served soon by legal help desk");
}
}
}
public class Customer
{
public string Name { get; set; }
public ComplaintType ComplaintType { get; set; }
}
public enum ComplaintType
{
General,
Critical,
Legal
}
void Main()
{
CustomerServiceDesk _frontLineDesk = new FrontLineServiceDesk();
CustomerServiceDesk _criticalSupportDesk = new CriticalIssueServiceDesk();
CustomerServiceDesk _legalSupportDesk = new LegalissueServiceDesk();
_frontLineDesk.SetupHadler(_criticalSupportDesk);
_criticalSupportDesk.SetupHadler(_legalSupportDesk);
Customer _customer1 = new Customer();
_customer1.Name = "Microsoft";
_customer1.ComplaintType = ComplaintType.General;
Customer _customer2 = new Customer();
_customer2.Name = "SunSystems";
_customer2.ComplaintType = ComplaintType.Critical;
Customer _customer3 = new Customer();
_customer3.Name = "HP";
_customer3.ComplaintType = ComplaintType.Legal;
_frontLineDesk.ServeCustomers(_customer1);
_frontLineDesk.ServeCustomers(_customer2);
_frontLineDesk.ServeCustomers(_customer3);
}
问题:
在不打破责任链的情况下,如何应用委托和事件来重写代码?如果我理解正确……您可以删除
SetupHandler
方法,并引入OnElevateQuery
事件。您的CriticalHelpDesk
对象是否可以处理FrontLineHelpDesk.OnElevateQuery
事件和您的LegalHelpDesk
对象可以处理CriticalHelpDesk.OnElevateQuery
事件。OnElevateQuery
事件可以在事件args中传递客户
范例
用法
但是,由于查询类型基于枚举
投诉类型
,您是否考虑过使用帮助桌面工厂
,该工厂可能会返回一个通用接口,例如IHelpDesk
。听起来您也可以在这个特定示例中使用策略模式 拥有投诉类型的客户看起来像是放置错误的属性。我想你是说投诉有一种类型
我可能错了,在这种情况下,你可以指出缺失了什么行为
这对我来说就像一件大事。每个事件处理程序都将按订阅顺序调用。每个处理人都可以根据投诉自由忽略通知。只要eventArgs的Handled属性为false并且存在挂起的订阅者,就会调用下一个处理程序
class ComplaintSource
{
public delegate void ComplaintHandler(Complaint complaint, HandledEventArgs evtArgs);
public event ComplaintHandler NewComplaint;
// code that raises the NewComplaint event as appropriate.
public void DoStuffThatRaisesTheEvent()
{
var evtArgs = new HandledEventArgs();
var theComplaint = new Complaint();
if (null == this.NewComplaint)
return;
Delegate[] list = NewComplaint.GetInvocationList();
foreach (Delegate del in list)
{
if (evtArgs.Handled)
break;
ComplaintHandler handler = (ComplaintHandler)del;
handler(theComplaint, evtArgs);
}
}
}
class FrontLineServiceDesk
{
FrontLineServiceDesk(ComplaintSource source)
{ source.NewComplaint += HandleGeneralComplaint; }
void HandleGeneralComplaint(Complaint complaint, HandledEventArgs evtArgs) { ...
// set evtArgs.Handled = true if you've handled the complaint
// this will stop the chain
}
}
class CriticalIssueServiceDesk
{
CriticalIssueServiceDesk(ComplaintSource source)
{ source.NewComplaint += HandleGeneralComplaint; }
void HandleCriticalComplaint(Complaint complaint, HandledEventArgs evtArgs) { ... }
}
// finally set the ball in motion
var source = new CompaintSource();
var frontLineDesk = new FrontLineServiceDesk(source);
var criticalIssueDesk = new CriticalIssueServiceDesk(source);
source.DoStuffThatRaisesTheEvent();
这与上述答案非常相似,但更加精简。:)
他试图理解责任链,而不是编写完成这项工作的最佳代码。非常好的解释,感谢您建议HelpDeskFactory。我喜欢流线型版本比其他版本更长的事实。在不开玩笑的方面,这个版本有点硬编码的阶段。e、 g.要在链中添加新的中间步骤,您必须修改现有类-更重要的是,每个阶段都了解下一个阶段(在本例中包含/创建它)。我要松开这里的联轴器……是的,我同意。更多的是设计上的改变。这样说似乎合乎逻辑。。但需求可能有所不同。我刚刚提出了我的想法。的确,这取决于设计的需要。您的示例很好地演示了如何使用代理。顺便说一句,代码可能比你的长,因为你忽略了大部分=D-1:我认为你遗漏了将投诉升级到下一级责任的代码。如果您不同意,请告诉我。您只是增加了类依赖性
CustomerServiceDesk _frontLine = new FrontLineServiceDesk();
CustomerServiceDesk _criticalLine = new CriticalLineServiceDesk();
CustomerServiceDesk _legalLine = new LegalLineServiceDesk();
// hook up events
_frontLine.OnElevateQuery += _critialLine.ServeCustomer;
_criticalLine.OnElevateQuery += _legalLine.ServeCustomer;
Customer _customer1 = new Customer();
_customer1.Name = "Microsoft";
_customer1.ComplaintType = ComplaintType.General;
Customer _customer2 = new Customer();
_customer2.Name = "SunSystems";
_customer2.ComplaintType = ComplaintType.Critical;
Customer _customer3 = new Customer();
_customer3.Name = "HP";
_customer3.ComplaintType = ComplaintType.Legal;
_frontLine.ServeCustomer(_customer1);
_frontLine.ServeCustomer(_customer2);
_frontLine.ServeCustomer(_customer3);
class ComplaintSource
{
public delegate void ComplaintHandler(Complaint complaint, HandledEventArgs evtArgs);
public event ComplaintHandler NewComplaint;
// code that raises the NewComplaint event as appropriate.
public void DoStuffThatRaisesTheEvent()
{
var evtArgs = new HandledEventArgs();
var theComplaint = new Complaint();
if (null == this.NewComplaint)
return;
Delegate[] list = NewComplaint.GetInvocationList();
foreach (Delegate del in list)
{
if (evtArgs.Handled)
break;
ComplaintHandler handler = (ComplaintHandler)del;
handler(theComplaint, evtArgs);
}
}
}
class FrontLineServiceDesk
{
FrontLineServiceDesk(ComplaintSource source)
{ source.NewComplaint += HandleGeneralComplaint; }
void HandleGeneralComplaint(Complaint complaint, HandledEventArgs evtArgs) { ...
// set evtArgs.Handled = true if you've handled the complaint
// this will stop the chain
}
}
class CriticalIssueServiceDesk
{
CriticalIssueServiceDesk(ComplaintSource source)
{ source.NewComplaint += HandleGeneralComplaint; }
void HandleCriticalComplaint(Complaint complaint, HandledEventArgs evtArgs) { ... }
}
// finally set the ball in motion
var source = new CompaintSource();
var frontLineDesk = new FrontLineServiceDesk(source);
var criticalIssueDesk = new CriticalIssueServiceDesk(source);
source.DoStuffThatRaisesTheEvent();
public abstract class CustomerServiceDesk
{
protected CustomerServiceDesk()
{
ServeCustomers = doServeCustomers;
}
protected CustomerServiceDesk m_ServiceDesk = null;
protected abstract void doServeCustomers(Customer _customer);
public delegate void ServeCustomersDelegate(Customer _customer);
public ServeCustomersDelegate ServeCustomers = null;
}
public class LegalissueServiceDesk : CustomerServiceDesk
{
public LegalissueServiceDesk()
{
}
protected override void doServeCustomers(Customer _customer)
{
if (_customer.ComplaintType == ComplaintType.Legal)
{
Console.WriteLine(_customer.Name + " - Complaints are registered ; will be served soon by legal help desk.\n");
}
}
}
public class CriticalIssueServiceDesk : CustomerServiceDesk
{
public CriticalIssueServiceDesk()
{
m_ServiceDesk = new LegalissueServiceDesk();
ServeCustomers += m_ServiceDesk.ServeCustomers;
}
protected override void doServeCustomers(Customer _customer)
{
if (_customer.ComplaintType == ComplaintType.Critical)
{
Console.WriteLine(_customer.Name + " - Complaints are registered ; will be served soon by Critical Help Desk.\n");
}
}
}
public class FrontLineServiceDesk : CustomerServiceDesk
{
public FrontLineServiceDesk()
{
m_ServiceDesk = new CriticalIssueServiceDesk();
ServeCustomers += m_ServiceDesk.ServeCustomers;
}
protected override void doServeCustomers(Customer _customer)
{
if (_customer.ComplaintType == ComplaintType.General)
{
Console.WriteLine(_customer.Name + " - Complaints are registered ; will be served soon by FrontLine Help Desk.\n");
}
}
}
public class Customer
{
public string Name;
public ComplaintType ComplaintType;
}
public enum ComplaintType
{
General,
Critical,
Legal
}
class Program
{
static void Main(string[] args)
{
Customer _customer1 = new Customer();
_customer1.Name = "Microsoft";
_customer1.ComplaintType = ComplaintType.General;
Customer _customer2 = new Customer();
_customer2.Name = "SunSystems";
_customer2.ComplaintType = ComplaintType.Critical;
Customer _customer3 = new Customer();
_customer3.Name = "HP";
_customer3.ComplaintType = ComplaintType.Legal;
FrontLineServiceDesk _frontLineDesk = new FrontLineServiceDesk();
_frontLineDesk.ServeCustomers(_customer1);
_frontLineDesk.ServeCustomers(_customer2);
_frontLineDesk.ServeCustomers(_customer3);
Console.In.ReadLine();
}
}