2010-04-14 25 views
5

Vì mục đích hiểu biết của tôi, tôi đã triển khai mẫu Chuỗi trách nhiệm.C# Chuỗi trách nhiệm với các đại biểu

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

Câu hỏi

Nếu không phá vỡ chuỗi-of-trách nhiệm, làm thế nào tôi có thể áp dụng các đại biểu và các sự kiện phải viết lại mã?

Trả lời

7

Nếu tôi hiểu bạn một cách chính xác ... những gì bạn có thể làm là loại bỏ các phương pháp SetupHandler và giới thiệu một sự kiện OnElevateQuery là đối tượng CriticalHelpDesk của bạn có thể xử lý các sự kiện FrontLineHelpDesk.OnElevateQuery và đối tượng LegalHelpDesk của bạn có thể xử lý các sự kiện CriticalHelpDesk.OnElevateQuery. Sự kiện OnElevateQuery có thể vượt qua khách hàng trong sự kiện args.

Ví dụ

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

Cách sử dụng

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

Tuy nhiên, như các loại truy vấn được dựa trên enum ComplaintType có bạn xem là sử dụng có lẽ là một HelpDeskFactory mà có thể trở lại một giao diện chung ví dụ IHelpDesk. Có vẻ như bạn cũng có thể sử dụng Mẫu chiến lược cho ví dụ cụ thể này.

+0

Giải thích tuyệt vời, Cảm ơn bạn đã đề xuất HelpDeskFactory. – user274364

+0

@nettguy: không thành vấn đề :) – James

2

Khách hàng có khiếu nạiType trông giống như thuộc tính bị đặt sai chỗ. Tôi cho rằng bạn có nghĩa là Đơn khiếu nại có Loại.

Tôi có thể sai trong trường hợp này bạn có thể chỉ ra hành vi nào bị thiếu Điều này giống như một sự kiện đối với tôi. Mỗi trình xử lý sự kiện sẽ được gọi theo thứ tự đăng ký. Mỗi người xử lý được tự do bỏ qua thông báo dựa trên khiếu nại. Trình xử lý tiếp theo được gọi là miễn là thuộc tính Handled của eventArgs là false và có các thuê bao đang chờ xử lý.

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(); 
+3

Anh ấy đang cố hiểu chuỗi trách nhiệm, không viết mã tốt nhất để thực hiện công việc này. –

+0

@Gishu Cảm ơn bạn rất nhiều – user274364

-1

Điều này rất giống với câu trả lời ở trên, nhưng được sắp xếp hợp lý hơn. :)

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

Yêu thích thực tế là phiên bản sắp xếp hợp lý dài hơn phần còn lại. Về phía không đùa, phiên bản này đã loại cứng các giai đoạn. ví dụ. để thêm một bước trung gian mới trong chuỗi, bạn phải sửa đổi một lớp hiện có - quan trọng hơn là mỗi giai đoạn có kiến ​​thức về giai đoạn tiếp theo (và chứa/tạo nó trong trường hợp này). Tôi muốn nới lỏng khớp nối ở đây .. – Gishu

+0

Vâng, tôi đồng ý. Thay đổi thiết kế của nó nhiều hơn. Nó có vẻ hợp lý để đặt nó theo cách này .. nhưng nhu cầu có thể khác nhau. Tôi chỉ trình bày ý tưởng của mình. Quả thật, nó phụ thuộc vào nhu cầu của thiết kế. Ví dụ của bạn làm công việc đủ tốt để chứng minh việc sử dụng các đại biểu. BTW, mã có vẻ dài hơn của bạn bởi vì bạn bỏ qua hầu hết nó = D – Nayan

+0

-1: Tôi nghĩ rằng bạn đang thiếu mã để leo thang khiếu nại lên cấp độ trách nhiệm tiếp theo. Hãy cho tôi biết nếu bạn không đồng ý. –

Các vấn đề liên quan