Шаблон за локатор на услуги и внедряване на Java

1. Въведение

В този урок ще научим за модела за проектиране на Service Locator в Java .

Ще опишем концепцията, ще приложим пример и ще подчертаем плюсовете и минусите на нейното използване.

2. Разбиране на модела

Целта на модела Service Locator е да връща екземплярите на услугата при поискване. Това е полезно за отделяне на потребителите на услуги от конкретни класове.

Прилагането ще се състои от следните компоненти:

  • Клиент - клиентският обект е потребител на услуга. Той е отговорен за извикване на заявката от локатора на услуги
  • Service Locator - е комуникационна входна точка за връщане на услугите от кеша
  • Кеш - обект за съхраняване на референции за услуги, за да ги използва повторно по-късно
  • Инициализатор - създава и регистрира препратки към услуги в кеша
  • Услуга - компонентът Услуга представлява оригиналните услуги или тяхното внедряване

Оригиналният сервизен обект се търси от локатора и се връща при поискване.

3. Прилагане

Сега, нека да станем практични и да разгледаме концепциите чрез пример.

Първо ще създадем интерфейс MessagingService за изпращане на съобщения по различни начини:

public interface MessagingService { String getMessageBody(); String getServiceName(); }

След това ще дефинираме две реализации на интерфейса по-горе, които изпращат съобщения по имейл и SMS:

public class EmailService implements MessagingService { public String getMessageBody() { return "email message"; } public String getServiceName() { return "EmailService"; } }

В SMSService определението клас е подобен на EmailService клас.

След дефинирането на двете услуги, трябва да дефинираме логиката за тяхното инициализиране:

public class InitialContext { public Object lookup(String serviceName) { if (serviceName.equalsIgnoreCase("EmailService")) { return new EmailService(); } else if (serviceName.equalsIgnoreCase("SMSService")) { return new SMSService(); } return null; } }

Последният компонент, от който се нуждаем, преди да съберем обекта на локатора на услуги, е кешът.

В нашия пример това е прост клас със свойство List :

public class Cache { private List services = new ArrayList(); public MessagingService getService(String serviceName) { // retrieve from the list } public void addService(MessagingService newService) { // add to the list } } 

И накрая, можем да приложим нашия клас за локатор на услуги:

public class ServiceLocator { private static Cache cache = new Cache(); public static MessagingService getService(String serviceName) { MessagingService service = cache.getService(serviceName); if (service != null) { return service; } InitialContext context = new InitialContext(); MessagingService service1 = (MessagingService) context .lookup(serviceName); cache.addService(service1); return service1; } }

Логиката тук е доста проста.

Класът съдържа екземпляр на кеша. След това в метода getService () първо ще провери кеша за екземпляр на услугата.

След това, ако това е нула, тя ще извика инициализиращата логика и ще добави новия обект към кеша.

4. Тестване

Нека да видим как можем да получим екземпляри сега:

MessagingService service = ServiceLocator.getService("EmailService"); String email = service.getMessageBody(); MessagingService smsService = ServiceLocator.getService("SMSService"); String sms = smsService.getMessageBody(); MessagingService emailService = ServiceLocator.getService("EmailService"); String newEmail = emailService.getMessageBody();

Първият път, когато получите EmailService от ServiceLocator нов екземпляр е създаден и се върна . След това, след като го извикате следващия път, EmailService ще бъде върнат от кеша.

5. Локатор на услуги срещу инжектиране на зависимост

На пръв поглед моделът на Service Locator може да изглежда подобно на друг добре познат модел - а именно, инжектиране на зависимост.

Първо, важно е да се отбележи, че както инжектирането на зависимост , така и моделът на локатора на услуги са изпълнения на концепцията за инверсия на контрола .

Преди да продължите по-нататък, научете повече за инжектирането на зависимост в това описание.

Ключовата разлика тук е, че клиентският обект все още създава своите зависимости . Той просто използва локатора за това, което означава, че се нуждае от препратка към обекта на локатора.

За сравнение, когато се използва инжекция на зависимости, на класа се дават зависимостите. Инжекторът се извиква само веднъж при стартиране, за да инжектира зависимости в класа.

И накрая, нека разгледаме няколко причини да избягваме да използваме шаблона Service Locator.

Един аргумент срещу това е, че затруднява модулното тестване. С инжектиране на зависимост можем да предадем фалшиви обекти от зависимия клас на тествания екземпляр. От друга страна, това е тясно място с модела Service Locator.

Друг проблем е, че е по-сложно да се използват API, базирани на този модел. Причината за това е, че зависимостите са скрити вътре в класа и те се проверяват само по време на изпълнение.

Въпреки всичко това, моделът Service Locator е лесен за кодиране и разбиране и може да бъде чудесен избор за малки приложения.

6. Заключение

Това ръководство показва как и защо да използваме шаблона за проектиране на Service Locator. Той обсъжда ключовите разлики между модела на проектиране на Service Locator и концепцията за инжектиране на зависимост.

Като цяло, разработчикът трябва да избере как да проектира класовете в приложението.

Моделът на Service Locator е ясен модел за отделяне на кода. Въпреки това, в случай на използване на класовете в множество приложения, инжектирането на зависимости е правилният избор.

Както обикновено, пълният код е достъпен в проекта Github.