Ответ
Сервис Локатор (Service Locator) — это паттерн проектирования, который выступает в роли централизованного реестра, предоставляющего доступ к различным сервисам (зависимостям) приложения. Вместо того чтобы создавать сервисы напрямую, клиентский код запрашивает их у локатора. С точки зрения QA, понимание этого паттерна важно для тестирования конфигурации и интеграции компонентов.
Основная идея: Скрыть сложность создания и нахождения сервисов, уменьшая связанность между классами.
Пример простой реализации на Java:
import java.util.HashMap;
import java.util.Map;
// Класс-локатор сервисов
public class ServiceLocator {
private static final Map<Class<?>, Object> services = new HashMap<>();
// Регистрация сервиса в локаторе
public static <T> void registerService(Class<T> interfaceClass, T implementation) {
services.put(interfaceClass, implementation);
}
// Получение сервиса из локатора
public static <T> T getService(Class<T> interfaceClass) {
return (T) services.get(interfaceClass);
}
}
// Интерфейс и его реализация
interface Logger {
void log(String message);
}
class FileLogger implements Logger {
@Override
public void log(String message) {
System.out.println("Log to file: " + message);
}
}
// Использование в коде приложения
public class MyApp {
public void doWork() {
Logger logger = ServiceLocator.getService(Logger.class);
logger.log("Application started");
}
}
// Конфигурация (обычно при старте приложения)
class AppConfig {
public static void configure() {
ServiceLocator.registerService(Logger.class, new FileLogger());
}
}
Влияние на процесс тестирования (QA):
-
Плюс для модульного тестирования: В тестах можно легко подменить реальный сервис на mock- или stub-объект, зарегистрировав его в локаторе перед запуском теста.
@Test public void testDoWork() { // Подменяем реальный логгер на заглушку Logger mockLogger = Mockito.mock(Logger.class); ServiceLocator.registerService(Logger.class, mockLogger); MyApp app = new MyApp(); app.doWork(); // Проверяем, что метод log был вызван Mockito.verify(mockLogger).log("Application started"); } - Минус — скрытые зависимости: Паттерн делает зависимости неявными. Класс
MyAppне показывает, что ему нуженLogger, что усложняет анализ кода и может привести к ошибкам времени выполнения, если сервис не был зарегистрирован. Это критичный момент для интеграционного тестирования — нужно проверять корректность конфигурации локатора. - Альтернатива — Внедрение зависимостей (DI): В современных фреймворках (Spring, Guice) чаще используется DI, где зависимости передаются явно (через конструктор или сеттер), что делает код более прозрачным и удобным для тестирования.