2009-10-23 2 views
2

Я пытаюсь определить лучший шаблон дизайна, который будет использоваться для веб-службы проверки бизнес-ключа. Ниже приводится базовый логический поток. Программа примет параметр и использует поле, чтобы определить путь к поиску нескольких систем, где этот бизнес-ключ можно найти. Сначала выполняется поиск в System1, если не найден, поиск System2 и System3. Логика поиска System1 зависит от поля в параметре, переданном в исходный метод проверки.Какие шаблоны проектирования используются для реализации этой бизнес-логики?

Я не совсем уверен, какой шаблон дизайна использовать. Это похоже на команду, цепочку ответственности, метод шаблонов, которые можно использовать здесь.

С моей реализации ниже, я вижу следующие проблемы:

  1. Каждый метод SearchSystemX нуждается в знать возвращать нулевое значение, если ключ бизнес не найден, так что метод «контроль» будет продолжать искать другие системы.

  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? 
    } 
} 

Instantiate

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. Кроме того, где будет определена эта цепочка? –

+0

Мне нравится эта реализация, но внутри SearchSystem1 существует условный поток, основанный на критериях. Кроме того, иногда, если он найден в одной системе, это означает, что мы хотим собирать дополнительные данные из другой системы. Не знаете, как бы вы выразили это в цепочке, поскольку вы можете либо вернуть значение null, либо результат. – JustinDSN

+0

Трудно сказать, почему бы вам не опубликовать код и посмотреть, что это значит? – OscarRyz

1

Возможно Strategy Pattern.

Это позволяет вам абстрагироваться от алгоритмов, которые вы используете для выполнения логики, инкапсулировать их в свои собственные объекты, а затем использовать их взаимозаменяемо во всем приложении (разрешить вызывающему определить, какой алгоритм использовать).

1

я бы, вероятно, использовать шаблон стратегии здесь путем определения интерфейса для поисковой системы (ы):

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

, а затем передать их в метод проверки (хотя класс валидации может получить их откуда-то еще).

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"); 
    } 
} 
Смежные вопросы