Рефакторинг шаблонов проектирования: применение шаблона адаптера к стороннему API

Чтобы получить доступ к данным для нашей базы данных учетных записей, нам нужно пройти через сторонний API, который представляет собой просто еще одну сборку, добавленную в качестве ссылки на наше решение.

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

 ICustomers customerCollection =GetCollection(OrgId,OrgUnit,CustomerInfo, "Customers");
       {
           customerCollection.Filter.Add("MasterCustomerId", QueryOperatorEnum.Equals, masterCustomerID);
           customerCollection.Filter.Add("SubCustomerId", QueryOperatorEnum.Equals,subCustomerID);
       }
       customerCollection.Fill();

После вызова customerCollection.Fill() API обращается к базе данных и выполняет запрос с соответствующими фильтрами. Возвращаемые объекты принадлежат API. В рамках этой службы существует множество вызовов API с уникальными требованиями к фильтрации.

Что я хотел бы сделать, так это использовать шаблон адаптера, чтобы поместить эти вызовы за мои собственные классы и вернуть объекты, которыми я владею. Затем я могу кодировать свои адаптеры из моей службы и позволить им беспокоиться о вызовах стороннего API.

Проблема в том, что я не знаю, как правильно обрабатывать все варианты фильтров, чтобы не просто воссоздать синтаксис фильтрации в своих адаптерах.

Я мог бы создать расширенные/статические методы, которые превращают систему фильтрации API в свободный синтаксис, и это могло бы выглядеть так:

customerCollection.Filter(“MasterCustomerId).Equals(masterCustomerId).Filter(SubCustomerId).Equals(subCustomerId).Fill();

Но что-то в этом просто кажется неправильным. Я чувствую, что возлагаю на службу слишком большую ответственность, чтобы делать все эти звонки.

Я усердно работаю над развитием своих объектно-ориентированных навыков, и я был бы признателен, если бы кто-нибудь помог указать мне правильное направление в этом вопросе.


person letsgetsilly    schedule 08.03.2011    source источник


Ответы (1)


Я бы не стал пытаться воссоздать их API с вашими объектами. Это создаст очень тесно связанную ассоциацию и вряд ли принесет вам много пользы.

Ваш адаптер, вероятно, должен предоставлять более ориентированный на домен интерфейс, например.

public IList<MyCustomerObjects> GetCustomers()
{
    //Call out to the third party API with the appropriate filters

    //foreach object in 3rd party collection, wrap in adapter class and add to list

    //return list of your objects
}

(Кстати, это в значительной степени шаблон репозитория из дизайна, управляемого доменом).

Другими словами, вы позволяете адаптеру беспокоиться о том, какие критерии фильтрации необходимы в стороннем API, а ваш вызывающий код имеет дело с разумными концепциями уровня бизнеса/домена.

person Paolo    schedule 08.03.2011
comment
Вы также можете использовать что-то вроде automapper для преобразования собственных объектов API в свои собственные. В качестве альтернативы вы можете написать метод расширения, который выполняет преобразования для вас. - person jonezy; 09.03.2011
comment
По сути, шаблон, который вы описываете, - это то, над чем я работаю, но я немного смущен тем, как правильно к нему подходить. С точки зрения моего клиентского кода (службы) я хочу вызвать что-то вроде этого: return _repository.GetCustomers(masterCustomerId); Однако в этом вызове должны выполняться некоторые бизнес-правила, поэтому мне нужен дополнительный слой/шаблон для реализации этих бизнес-правил. Прямо сейчас я называю этот слой «фасадом», но я не знаю, правильный ли это подход. - person letsgetsilly; 10.03.2011