2011-08-08 58 views
9

Ứng dụng tôi đang làm việc trên các quy trình Mục công việc. Tùy thuộc vào trạng thái của một mục công việc có một số hành động có sẵn. "Hoàn thành" "Hủy" "định lại" vv ...Đề xuất mẫu thiết kế

Để cung cấp các chức năng cho những hành động Tôi hiện đang có một giao diện trông giống như thế này ...

public interface IActionProvider{ 
    public void Complete(WorkItem workItem); 
    public void Cancel (WorkItem workItem); 
    public void Reassign(WorkItem workItem); 
} 

Sau đó, dựa trên các chi tiết khác của mục công việc tôi có triển khai cụ thể của giao diện. Chỉ cần ví dụ ...

public class NormalActionProvider :IActionProvider 
{ 
    ... 
} 

public class UrgentActionProvider : IActionProvider 
{ 
    .... 
} 

Vấn đề là, nếu tôi muốn thêm một hành động mới, nói ... "Đại biểu" Tôi phải cập nhật giao diện mà các khóa học có hiệu ứng trên tất cả các triển khai.

Điều này có vi phạm Nguyên tắc mở/đóng không? Bạn có thể giới thiệu một mẫu thiết kế hoặc trình cấu trúc lại có thể giúp tôi ở đây không?

Trả lời

11

Có vẻ như mẫu lệnh sẽ phù hợp. Bạn có thể sửa đổi/thêm các lệnh khác. Các lớp lệnh được tách riêng khỏi chương trình chính.

public interface IActionProvider{ 
    public void execute(WorkItem item,ActionType actionType); 
} 

Loại hành động đại diện hoàn thành, hủy &, v.v. Bạn có thể tiếp tục thêm các loại hành động khác & plugin các lớp lệnh thích hợp.

0

Tùy thuộc vào những gì bạn thực sự đang cố gắng thực hiện với IActionProvider của mình. Nếu bạn thực sự muốn làm cho nó để mỗi thực hiện phải có khả năng thực hiện tất cả các hành động mà bạn cho là quan trọng, thì đó phải là một phần của giao diện mà chúng thực hiện. Giao diện hoạt động tốt nhất nếu chúng được lên kế hoạch tốt trước thời hạn để chúng không phải thay đổi liên tục.

Nhưng có vẻ như bạn không nhất thiết muốn tất cả các hành động được thực hiện bởi tất cả các nhà cung cấp. Tôi cần phải biết thêm chi tiết để có thể đưa ra lời khuyên tốt, nhưng một ví dụ sẽ là để các nhà cung cấp khởi tạo bản thân họ chống lại một loại Bus sự kiện. Họ có thể đăng ký các sự kiện mà họ quan tâm và chỉ thực hiện các hành động cho các sự kiện có ý nghĩa đối với việc triển khai cụ thể.

0

"Tùy thuộc vào trạng thái của workitem", mang đến cho các mẫu thiết kế Nhà nước

Một cách này hay cách khác, bạn sẽ phải cấu trúc lại bạn giao tiếp và cuối cùng phá vỡ hợp đồng của khách hàng.

Nếu tôi đã hiểu vấn đề của bạn một cách chính xác, thì bạn có một WorkItemProcessor có trạng thái thay đổi tùy thuộc vào trên WorkItem được gửi đến nó.

Do đó WorkItemProcessor của bạn trở nên

// Context 
    public class WorkItemProcessor 
    { 
     public IState CurrentState { get; set; } 

     public WorkItemProcessor(IState initialState) 
     { 
      CurrentState = initialState; 
     } 

     public void Process(WorkItem workItem) 
     { 
      CurrentState.Handle(this, workItem); 
     } 
    } 

Sau đó, chúng tôi xác định nhiều tiểu bang rằng WorkItemProcessor có khả năng có thể là trong

// State Contract 
    public interface IState 
    { 
     void Handle(WorkItemProcessor processor, WorkItem item); 
    } 

    // State One 
    public class CompleteState : IState 
    { 
     public void Handle(WorkItemProcessor processor, WorkItem item) 
     { 
      processor.CurrentState = item.CompletenessConditionHoldsTrue ? (IState) this : new CancelState(); 
     } 
    } 

    // State Two 
    public class CancelState : IState 
    { 
     public void Handle(WorkItemProcessor processor, WorkItem item) 
     { 
      processor.CurrentState = item.CancelConditionHoldsTrue ? (IState) this : new CompleteState(); 
     } 
    } 

Giả sử WorkItem bạn Hình như

// Request 
    public class WorkItem 
    { 
     public bool CompletenessConditionHoldsTrue { get; set; } 

     public bool CancelConditionHoldsTrue { get; set; } 
    } 

Để đặt nó tất cả cùng nhau

static void Main() 
    { 
     // Setup context in a state 
     WorkItemProcessor processor = new WorkItemProcessor(new CancelState()); 

     var workItem1 = new WorkItem { CompletenessConditionHoldsTrue = true }; 
     var workItem2 = new WorkItem { CancelConditionHoldsTrue = true }; 

     // Issue requests, which toggles state 
     processor.Process(workItem1); 
     processor.Process(workItem2); 

     Console.Read(); 
    } 

Hy vọng điều này sẽ giúp bạn gần gũi hơn. Chúc mừng.

0

Tôi cũng sẽ chọn mẫu lệnh. Để tăng cường, bạn có thể kết hợp nó với phương thức nhà máy trừu tượng, vì vậy bạn có thể có một lớp nhà máy cho mỗi lớp lệnh, và tất cả các nhà máy đó đều thực hiện một giao diện nhà máy chung.

Ví dụ:

// C# 
public interface ICommand { void Execute(); } 

public interface ICommandFactory { ICommand Create(); } 

public class CommandFactoryManager 
{ 
    private IDictionary<string, ICommandFactory> factories; 

    public CommandFactoryManager() 
    { 
     factories = new Dictionary<string, ICommandFactory>(); 
    } 

    public void RegisterCommandFactory(string name, ICommandFactory factory) 
    { 
     factories[name] = factory; 
    } 

    // ... 
} 

Bằng cách này, bạn có thể đăng ký nhà máy lệnh mới năng động. Ví dụ, bạn có thể tải một DLL tại thời gian chạy và lấy tất cả các lớp thực hiện giao diện ICommandFactory bằng cách sử dụng sự phản chiếu, và bạn có một hệ thống plugin đơn giản.

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