C# 委托责任链

发布于 2024-08-28 15:06:40 字数 2884 浏览 12 评论 0原文

为了我的理解目的,我实现了责任链模式。

//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);
}

问题

在不破坏责任链的情况下,我如何应用委托和事件来重写代码?

For my understanding purpose i have implemented Chain-Of-Responsibility pattern.

//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);
}

Question

Without breaking the chain-of-responsibility ,how can i apply delegates and events to rewrite the code?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

萌无敌 2024-09-04 15:06:40

如果我理解正确的话...您可以做的是删除 SetupHandler 方法并引入 OnElevateQuery 事件,如果您的 CriticalHelpDesk 对象可以处理FrontLineHelpDesk.OnElevateQuery 事件和您的 LegalHelpDesk 对象可以处理 CriticalHelpDesk.OnElevateQuery 事件。 OnElevateQuery 事件可以在事件参数中传递客户。

示例

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。听起来您也可以在这个特定示例中使用策略模式

If I understand you correctly...what you could do is remove the SetupHandler method and introduce an OnElevateQuery event were your CriticalHelpDesk object could handle the FrontLineHelpDesk.OnElevateQuery event and your LegalHelpDesk object could handle the CriticalHelpDesk.OnElevateQuery event. The OnElevateQuery event could pass the customer in the event args.

Example

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");
        }
    }
}

Usage

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);

However, as the query type is based on the enum ComplaintType have you considered using perhaps a HelpDeskFactory which could return a generic interface e.g. IHelpDesk. Sounds like you could also use the Strategy Pattern for this particular example.

抚你发端 2024-09-04 15:06:40

具有投诉类型的客户看起来像是一个放错位置的属性。我假设你的意思是投诉有一个类型。

我可能是错的,在这种情况下你可以指出缺少什么行为
对我来说这只是一个事件。每个事件处理程序将按订阅顺序调用。每个处理程序都可以根据投诉忽略通知。只要 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();

Customer having a complaintType looks like a misplaced attribute. I assume you mean a Complaint has a Type.

I may be wrong in which case you can point what behavior is missing
This just looks like an event to me. Each event handler would be called in order of subscription. Each handler is free to ignore the notification based on the complaint. The next handler is called as long as the Handled property of the eventArgs is false and there are pending subscribers.

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();
2024-09-04 15:06:40

这与上面的答案非常相似,但更精简。 :)

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();
    }
}

This is very similar to above answers, but more streamlined. :)

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();
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文