2011-08-08 12 views
9

Süreçler üzerinde çalıştığım bir uygulama İş Öğeleri. Bir iş öğesinin durumuna bağlı olarak, bir dizi eylem vardır.Bir tasarım desenini önerin

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

Sonra diğer ayrıntılarına göre ...

Şu anda şuna benzer bir arayüze sahip eylemler için işlevsellik sağlamak için ... vb "yeniden atama" "İptal" "Komple" iş öğesi arayüzün somut uygulamaları var. Sadece örneğin ...

public class NormalActionProvider :IActionProvider 
{ 
    ... 
} 

ve

public class UrgentActionProvider : IActionProvider 
{ 
    .... 
} 

ben diyelim ki, yeni bir işlem eklemek istiyorsanız Sorun, ... "Delege" Ben arayüzü güncellemek zorunda olan tabii Tüm uygulamalara etkileri vardır.

bu Aç/Kapat prensibi ihlal ediyor mu? Burada bana yardımcı olabilecek bir tasarım deseni veya refaktor tavsiye edebilir misiniz?

cevap

11

Komut deseni uygun gibi görünüyor. Daha fazla komut ekleyebilir/ekleyebilirsiniz. Komut sınıfları ana programdan ayrıştırılır.

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

ActionType Komple temsil vb & iptal edin. Daha fazla eylem türü & eklenti uygun komut sınıfları eklemeye devam edebilirsiniz.

0

O gerçekten IActionProvider ile gerçekleştirmek için çalışıyoruz bağlıdır. Bunu yapmak istediğinizde, her uygulamanın önemli olduğunu düşündüğünüz tüm eylemleri gerçekleştirebilmesi gerekiyorsa, bu, uyguladıkları arayüzün bir parçası olmalıdır. Arayüzler, iyi planlanmışlarsa iyi çalışırlar, böylece sürekli değişmek zorunda kalmazlar. mutlaka tüm eylemler tüm sağlayıcılar tarafından uygulanacak istemiyormuş gibi

Ama bu sesler. İyi tavsiyede bulunabilmek için daha fazla ayrıntı bilmem gerekirdi, ancak bir örnek, sağlayıcıların kendilerini bir tür Olay Veri Yoluna karşı başlatmalarıdır. İlgilendikleri olaylara abone olabilirler ve yalnızca belirli uygulama için anlamlı olan olaylar için harekete geçebilirler.

0

"Workitem durumuna bağlı olarak" Devlet tasarım deseni

Tek yön getiriyor ya da böyle, sen arayüz ve sonunda müşteri sözleşmelerini kırmak planı ayrı gerekecek.

Sorununuzu doğru bir şekilde anladıysam, o zaman WorkLink'e gönderilen durumu üzerinde durumuna bağlı bir WorkItemProcessor var.

nedenle sizin WorkItemProcessor

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

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

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

Sonra WorkItemProcessor potansiyel Workitem

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

     public bool CancelConditionHoldsTrue { get; set; } 
    } 

hepsini koymak için Görünüşe varsayarsak

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

içinde olabileceğini birden durumlarını tanımlamak olur birlikte

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

Bu sizi daha da yaklaştırır. Şerefe.

0

Komut şablonunu da seçerim. Bir geliştirme olarak, bunu soyut fabrika yöntemiyle birleştirebilirsiniz, böylece her bir komut sınıfı için bir fabrika sınıfına sahip olabilirsiniz ve tüm bu fabrikalar ortak bir fabrika arabirimini uygular. Örneğin

:

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

    // ... 
} 

Bu şekilde, dinamik yeni komuta fabrikalar kaydedebilirsiniz. Örneğin, çalışma zamanında bir DLL yükleyebilir ve yansımayı kullanarak ICommandFactory arabirimini uygulayan tüm sınıfları getirebilir ve basit bir eklenti sisteminiz vardır.