2009-10-23 29 views
2

我正在嘗試確定用於商業密鑰驗證Web服務的最佳設計模式。基本邏輯流程編碼如下。該程序將採用一個參數並使用一個字段來幫助確定搜索可找到該業務密鑰的多個系統的路徑。首先搜索System1,如果未找到,則搜索System2和System3。 System1搜索邏輯取決於傳遞給原始驗證方法的參數中的字段。要使用哪種設計模式來實現此業務邏輯?

我不太確定使用哪種設計模式。它看起來像命令,責任鏈,模板方法都可以在這裏使用。

下面我的實現,我看到以下問題:

  1. 每個SearchSystemX方法需要知道返回NULL如果找不到業務鍵,使「控制」的方法將繼續搜索其他系統。

  2. 每個SearchSystemX都必須知道如何填充業務對象,目前只是通過一個簡單的基本字符串來實現,但僅作爲示例。

請讓我知道您的想法。

public string Validate (string parms) { 
string returnValue = null; 

returnValue = SearchSystem1(parms); 

if (returnValue == null) { 
    returnValue = SearchSystem2(parms); 

    if (returnValue != null) { 
    returnValue = SearchSystem3(parms); 
    } 
    else if (returnValue == null) { 
    if (parms == "Criteria1") { 
    returnValue = SearchSystem4(parms); 

    if (returnValue == null) { 
    throw new ApplicationException("ID Invalid"); 
    } 
    } 
    else if (parms == "Criteria2") { 
    throw new ApplicationException("ID Invalid"); 
    } 
    } 
} 
return returnValue; 

private string SearchSystem1 (string parms) { 
string returnValue = null; 

if (parms == "Criteria1") { 
    returnValue = SearchSystem1UsingColumn1(parms); 
} 
else if (parms == "Criteria2") { 
    returnValue = SearchSystem1UsingColumn2(parms); 

    if (returnValue == null) { 
    returnValue = SearchSystem1UsingColumn4(parms); 
    } 
} 

if (returnValue != null) { 
    returnValue = FetchXYCoordinate(parms); 
} 

return returnValue; 
} 

謝謝!

回答

2

Chain of responsability

每個處理對象包含一組邏輯描述類型,它可以處理命令對象,並且如何通過關閉那些,它不能給鏈下一個處理對象

所以你定義和抽象SearchSystem(或SystemSearch),並添加子是這樣的:

class SearchSystem 
{ 
    //link to the next in the chain 
    SearchSystem next; 

    // Basic search, If cannot handle forward to the next. 
    public Result search(Criteria c) 
    { 
     Result r = doSearch(c); 

     if(r != null) 
     { 
      return r; 
     } 

     return next.search(c); 
    } 
    // subclass specific system search 
    abstract Result doSearch(Criteria c); 
} 

class SearchSystemOne: SearchSystem 
{ 
    Result doSearch(Criteria c) 
    { 
     // do some system 1 speficif stuff 
     // and return either and instance or null 
    } 
} 
class SearchSystemTwo: SearchSystem 
{ 
    Result doSearch(Criteria c) 
    { 
     // do some system 2 speficif stuff 
     // and return either and instance or null 
    } 
} 
.... etc etc. 
// End of the chain 
class SearchSystemOver: SearchSystem 
{ 
    public Result search(Criteria c) 
    { 
     throw new ApplicationException("Criteria not foud", c); 
    } 
    Result doSearch(Criteria c) 
    { 
     // didn't we throw exception already? 
    } 
} 

實例化

SearchSystem one = new SearchSystemOne(); 
SearchSystem two = new SearchSystemTwo(); 
SearchSystem three = new SearchSystemThree(); 
SearchSystem four = new SearchSystemFour(); 
SearchSystem over = new SearchSystemOver(); 

,並建立連鎖

one.next = two; 
two.next = three; 
three.next = four; 
four.next = over; 

最後搜索。

SearchSystem searcher = one; 

searcher.search(Criteria.addName("Oscar").addLastName("Reyes")); 
+0

由於需求沒有指定需要動態構建鏈,這是CoR的核心優勢,這看起來像是過度殺傷。另外,這個鏈將被定義在哪裏? – 2009-10-23 19:25:00

+0

我喜歡這個實現,但是在SearchSystem1中有基於條件的條件流。此外,有時如果它在一個系統中找到,這意味着我們想要從另一個系統收集額外的數據。不知道如何在鏈中表達,因爲你可以返回null或結果。 – JustinDSN 2009-10-28 12:55:55

+0

很難說,你爲什麼不發佈代碼,看看是什麼 – OscarRyz 2009-10-28 15:23:25

1

可能是Strategy Pattern。它允許你抽象出你用來執行邏輯的算法,將它們封裝在它們自己的對象中,然後在應用程序中互換使用它們(允許調用者定義使用哪種算法)。

1

我可能會通過定義一個接口,用於搜索系統(S)在這裏使用的策略模式:

public interface ISearchStrategy 
{ 
    string Search(string criteria); 
} 

,然後將它們傳遞給validate方法(雖然驗證類能拿他們從別的地方)。

public string Validate(string parms, IEnumerable<ISearchStrategy> searchStrategies) 
{ 
    string returnValue = null; 

    foreach(var strategy in searchStrategies) 
    { 
     if(returnValue == null) 
     { 
      returnValue = strategy.Search(parms); 
     } 
    } 

    if(returnValue == null) throw new ApplicationException("ID invalid"); 
    return returnValue; 
} 
1

不知道更多關於你的域名,我只能建議小改動。首先將使用guard clauses

此外您還提到了SearchSystems需要如何知道如何構建業務對象。我會確保SearchSystems可以被多態處理(這樣你就有了重構策略或某種依賴注入的途徑)。此外,我會贊成SystemSearcher通過一系列SearchSystem方法。然後我會在SearchSystems中注入一個業務對象工廠。我也會用TryXXX語義來設計行爲。

public interface ISearchSystem 
{ 
    bool TryGet(string parms, out string businessObject); 
} 

public class System1Searcher : ISearchSystem 
{ 
    public System1Searcher(BusinessObjectFactory factory) { _factory = factory; } 
    private field BusinessObjectFactory _factory; 
    public bool TryGet(string parms, out string businessObject) 
    { 
    // do internal logic 
    return _factory.Create(string stuff); 
    } 
} 

public class Service 
{ 
    // is "Validate" the correct metaphor for this logic? 
    public string Validate(string parms) 
    { 
    string returnValue = null; 
    if (new System1Searcher().TryGet(parms, out returnValue) 
     return returnValue; 

    if (new System2Searcher().TryGet(parms, out returnValue) 
     return returnValue; 

    if (new System3Searcher().TryGet(parms, out returnValue) 
     return returnValue; 

    if (new System4Searcher().TryGet(parms, out returnValue) 
     return returnValue; 

    // this message should be written in terms of the logic of this method 
    // such as "Parameters invalid" 
    throw new ApplicationException("ID Invalid"); 
    } 
} 
相關問題