Понимание шаблона проектирования Facade в C#
В этом посте мы собираемся работать с другим распространенным типом структурного паттерна, называемым фасадом. С точки зрения непрофессионала, шаблон Facade используется для предоставления простого интерфейса для довольно сложной системы.
Эта проблема
Иногда в нашей системе, имеющей n подсистем и модулей, существует жесткая потребность взаимодействовать со сторонними приложениями для извлечения, хранения или обмена данными.
Для плохо спроектированной системы клиенту необходимо знать такие детали, как форматы данных, URL-адреса службы, метаданные, протоколы вызова, тип ответа и так далее.
Решение: Фасад
В таких случаях было бы логично иметь общую систему, которая обеспечивает абстракцию всех этих сторонних сервисов. Эта система будет отвечать за взаимодействие и будет действовать как шлюз для клиента, чтобы общаться с ними, фактически не вникая в сложность системы.
Как и в приведенном выше представлении, клиент фактически хочет взаимодействовать с тремя внешними подсистемами Operation1(), Operation2() и Operation3(). Фасад действует как промежуточное программное обеспечение, предоставляя унифицированную и упрощенную конечную точку для выполнения этой работы.
Все 3 подсистемы могут сильно отличаться друг от друга, им может требоваться разный протокол для доступа, но для клиента все эти детали скрыты. Независимо от того, с какой подсистемой клиент хочет взаимодействовать, их последовательный способ сделать это
Реализация
Представьте, что мы хотим разработать социальный плагин, который позволяет пользователю вводить элемент, а услуга получает свою цену со всех популярных порталов электронной коммерции.
Фасадный паттерн здесь может быть действительно очень полезен, иначе клиентское приложение будет перегружено сложностью настройки обращений ко всем доступным порталам.
- Предположим, что есть три внешних сервиса, которые при вызове с идентификатором товара возвращают текущую цену.
GetPriceByIDFromAmazon(int productId)
GetPriceByIDFromFlipkart(int productISIN)
GetPriceByIDFromBestBuy(int shopItem)
- Фактическая реализация этих трех сервисов нам неизвестна, поскольку они являются внешними, и нам просто нужно настроить систему связи с ними и правильно передать идентификатор продукта, чтобы получить цену.
- Класс PriceAccumalator будет действовать как наш фасад, принимая идентификатор продукта от клиента и возвращая список цен от всех доступных поставщиков-партнеров.
- Клиенту здесь не нужно знать о существовании подсистемы. Для этого вызов PriceAccumator должен помочь.
public class PriceAccumalatedDetails { public int ProductId { get; set; } public List<PriceDetails> PriceDetails { get; set; } } public class PriceDetails { public decimal CurrentPrice { get; set; } public bool InStock { get; set; } public int VendorId {get;set;} public string VendorName {get;set;}
public string ProductLink {get;set;}
}
ЦенаНакопленнаяДетали это модель ответа, которую клиент будет ожидать после того, как он запросит информацию о цене продукта. Этот ответ будет содержать сведения о продукте и список объектов с информацией о ценах, сопоставленных для каждого поставщика.
Ниже могут быть примеры классов, которые фактически взаимодействуют со сторонними системами.
public class AmazonService { public AmazonService() { } public PriceDetails GetPriceByIDFromAmazon(int productId){
}
}
public class FlipkartService { public FlipkartService() { } public PriceDetails GetPriceByIDFromFlipkart(int productISIN){
}
}
public class BestBuyService { public BestBuyService() { } public PriceDetails GetPriceByIDFromBestBuy(int shopItem){
}
}
- Давайте теперь создадим наш класс Facade Прайс Аккумулятор который вызывает эти три службы внутренне, чтобы получить цену от каждой из них
public class PriceAccumalator { public PriceAccumalatedDetails GetPriceFromVendors(int productId){ List<PriceDetails> accumalatedPrice = new List<PriceDetails>(); AmazonService amazon = new AmazonService(); accumalatedPrice.Add(amazon.GetPriceByIDFromAmazon(productId)); FlipkartService flipkart = new FlipkartService(); accumalatedPrice.Add(flipkart.GetPriceByIDFromFlipkart(productId)); BestBuyService bestBuy = new BestBuyService(); accumalatedPrice.Add(amazon.GetPriceByIDFromBestBuy(productId)); return new PriceAccumalatedDetails() {
productId = productId,
PriceDetails = accumalatedPrice
};
}
}
Итак, теперь клиенту просто нужно знать о Прайс Аккумулятор который выполняет его требование. Эта реализация также позволяет добавлять новых поставщиков без каких-либо изменений со стороны клиента.
Как всегда, спасибо, что уделили свое время моему контенту, и я надеюсь, что это было полезно. До следующего раза, продолжайте учиться и продолжать строить.