Service Locator Pattern

2025. 1. 16. 16:33Spring Framework/Spring IoC

서비스 로케이터 패턴(Service Locator Pattern)은 애플리케이션에서 의존성 관리를 위한 디자인 패턴 중 하나로, 객체가 자신의 의존성을 얻기 위해 중앙화된 레지스트리 역할을 하는 서비스 로케이터를 사용하는 방식입니다. 이 패턴은 주로 객체가 직접 의존성을 생성하지 않고, 서비스 로케이터를 통해 필요한 의존성을 요청하여 얻는 구조를 제공합니다.

 

서비스 로케이터 패턴의 작동 방식

  1. 서비스 로케이터는 애플리케이션 내에서 서비스 객체(의존성)를 등록하고, 필요한 경우 이를 클라이언트에 제공하는 역할을 합니다.
  2. 클라이언트 객체는 서비스 로케이터에 의존하여 필요한 의존성을 조회하거나 검색(lookup)합니다.
  3. 서비스 로케이터는 의존성을 캐싱하거나, 필요에 따라 동적 생성하여 반환합니다.

 

구조

서비스 로케이터 패턴의 일반적인 구조는 다음과 같습니다:

  1. Service Interface: 제공되는 서비스의 인터페이스입니다.
  2. Service Implementation: 실제로 제공되는 서비스의 구현체입니다.
  3. Service Locator: 서비스 인스턴스를 등록하고 제공하는 중앙화된 레지스트리입니다.
  4. Client: 서비스 로케이터를 통해 필요한 서비스 객체를 얻어 사용하는 클라이언트 코드입니다.

 

예제 코드

서비스 로케이터 패턴

// 1. 서비스 인터페이스
public interface Service {
    void execute();
    String getName();
}

// 2. 서비스 구현체
public class ServiceA implements Service {
    @Override
    public void execute() {
        System.out.println("Executing ServiceA");
    }
    @Override
    public String getName() {
        return "ServiceA";
    }
}

public class ServiceB implements Service {
    @Override
    public void execute() {
        System.out.println("Executing ServiceB");
    }
    @Override
    public String getName() {
        return "ServiceB";
    }
}

// 3. 서비스 로케이터
import java.util.HashMap;
import java.util.Map;

public class ServiceLocator {
    private static Map<String, Service> services = new HashMap<>();

    // 서비스 등록
    public static void registerService(Service service) {
        services.put(service.getName(), service);
    }

    // 서비스 검색
    public static Service getService(String serviceName) {
        return services.get(serviceName);
    }
}

// 4. 클라이언트
public class Client {
    public static void main(String[] args) {
        // 서비스 등록
        ServiceLocator.registerService(new ServiceA());
        ServiceLocator.registerService(new ServiceB());

        // 서비스 사용
        Service serviceA = ServiceLocator.getService("ServiceA");
        serviceA.execute();

        Service serviceB = ServiceLocator.getService("ServiceB");
        serviceB.execute();
    }
}

 

 

서비스 로케이터 패턴의 특징

  1. 장점:
    • 의존성 관리의 중앙화: 모든 의존성을 한 곳에서 관리할 수 있습니다.
    • 유연성: 런타임에 의존성을 변경하거나 등록할 수 있습니다.
    • 코드 분리: 클라이언트는 의존성 생성 방법에 대해 알 필요가 없습니다.
  2. 단점:
    • 테스트 어려움: 클라이언트 코드가 서비스 로케이터에 강하게 결합되므로 단위 테스트가 어려울 수 있습니다.
    • 런타임 의존성 문제: 런타임 시 의존성 미등록 또는 잘못된 의존성으로 인해 오류가 발생할 수 있습니다.
    • 추적 복잡성 증가: 의존성 흐름이 복잡해질 수 있습니다.

 

의존성 주입(DI)과의 차이점

Spring IoC 컨테이너의 의존성 주입(DI)는 서비스 로케이터 패턴과 비교해 다음과 같은 차이를 보입니다:

특징 서비스 로케이터 패턴 의존성 주입 (DI)
의존성 조회 방식 클라이언트가 직접 서비스 로케이터를 호출 컨테이너가 클라이언트에 자동으로 의존성 제공
결합도 클라이언트와 서비스 로케이터 간 결합 존재 느슨한 결합 (loose coupling)
테스트 용이성 낮음 (로케이터 의존성 때문에) 높음 (클라이언트는 DI 컨테이너에 무관함)
구현 복잡성 상대적으로 간단 컨테이너 관리와 설정 필요

 

Spring IoC 컨테이너와 서비스 로케이터 패턴

Spring IoC 컨테이너는 서비스 로케이터 패턴 대신 의존성 주입 방식을 채택합니다. 의존성 주입은 객체 생성과 의존성 관리 책임을 IoC 컨테이너가 담당하여 클라이언트의 결합도를 줄이고, 테스트 가능성을 높이며, 코드를 더 간결하게 만듭니다.

서비스 로케이터 패턴은 Spring 이전의 전통적인 애플리케이션에서 많이 사용되었으나, 현재는 의존성 주입이 더 선호됩니다.

'Spring Framework > Spring IoC' 카테고리의 다른 글

엔터프라이즈 관련 기능  (1) 2025.01.16
Spring IoC  (0) 2024.11.15
The BeanFactory API  (0) 2024.11.15
Additional Capabilities of the ApplicationContext  (0) 2024.11.15
Registering a LoadTimeWeaver  (0) 2024.11.15