出于我的理解目的,我实施了责任链模式。
//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);
}
问题
在不破坏责任链的情况下,我如何应用委托和事件来重写代码?
答案 0 :(得分:9)
如果我理解正确...您可以执行的操作是删除SetupHandler
方法,并在您的OnElevateQuery
对象处理CriticalHelpDesk
事件时引入FrontLineHelpDesk.OnElevateQuery
事件并且您的LegalHelpDesk
对象可以处理CriticalHelpDesk.OnElevateQuery
事件。 OnElevateQuery
事件可以在事件args中传递客户。
实施例
public abstract class CustomerServiceDesk
{
public delegate void ElevateQueryEventHandler(Customer c);
public event ElevateQueryEventHandler OnElevateQuery;
public abstract void ServeCustomer(Customer c);
}
public class FrontLineServiceDesk : CustomerServiceDesk
{
public override void ServeCustomer(Customer c)
{
switch (c.ComplaintType)
{
case ComplaintType.General:
Console.WriteLine(c.Name + " Complaints are registered; will be served soon by FrontLine Help Desk");
break;
default:
OnElevateQuery(c);
}
}
}
public class CriticalIssueServiceDesk : CustomerServiceDesk
{
public override void ServeCustomer(Customer c)
{
switch (c.ComplaintType)
{
case ComplaintType.Critical:
Console.WriteLine(c.Name + " Complaints are registered; will be served soon by Critical Help Desk");
break;
case ComplaintType.Legal:
OnElevateQuery(c);
break;
default:
Console.WriteLine("Unable to find appropriate help desk for your complaint.");
break;
}
}
}
public class LegalIssueServiceDesk : CustomerServiceDesk
{
public override void ServeCustomer(Customer c)
{
if (c.CompliantType == CompliantType.Legal)
{
Console.WriteLine(c.Name + " Complaints are registered; will be served soon by Legal Help Desk");
}
else
{
// you could even hook up the FrontLine.ServeCustomer event
// to the OnElevateQuery event of this one so it takes the
// query back to the start of the chain (if it accidently ended up here).
Console.WriteLine("Wrong department");
}
}
}
用法的
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);
但是,由于查询类型基于枚举ComplaintType
,您考虑使用可能返回通用接口的HelpDeskFactory
,例如IHelpDesk
。对于这个特定的例子,听起来你也可以使用策略模式。
答案 1 :(得分:3)
拥有complaintType的客户看起来像是错位的属性。我认为你的意思是投诉有一个类型。
我可能错了,在哪种情况下你可以指出缺少什么行为 这对我来说就像是一件大事。将按订阅顺序调用每个事件处理程序。每个处理程序都可以根据投诉自由忽略通知。只要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();
答案 2 :(得分:-1)
这与上面的答案非常相似,但更加精简。 :)
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();
}
}