이 포스팅은 엔터프라이즈 애플리케이션 아키텍처 패턴 18장을 요약한 내용입니다.
분리 인터페이스(Seperated Interface)
구현과 분리된 별도의 패키지에 인터페이스를 정의한다.
시스템을 구성하는 부분 간의 의존성이 필요한 경우 인터페이스로 결합도를 최소한으로 가져가면서 의존할 수 있다.
작동원리
특정 객체에서 다른 객체의 기능이 필요할 때 직접 의존하지 않고 인터페이스를 통해서 의존하게 한다. 이 때 구현을 인스턴스화하기가 불편할 수 있는데 구현을 팩터리에 바인딩하는 플러그인 패턴을 사용하면 된다. (굳이 플러그인을 사용하지 않아도 됨)
사용 시점
프레임워크 패키지에 넣은 범용 추상 코드에서 특정한 애플리케이션 코드를 호출해야 한다.
한 계층의 코드에서 볼 수 없어야 하는 다른 계층의 코드를 호출해야 한다. (도메인에서 데이터 매퍼를 호출하는경우)
다른 개발 그룹에서 개발한 함수를 호출해야 하지만 해당 API에 대한 의존성을 원하지 않는다.
플러그인
컴파일이 아닌 구성 중(런타임)에 클래스를 연결한다.
애플리케이션 코드를 여러 런타임 환경에서 특정 동작에 따른 구현을 적용해 실행해야 하는 경우 분리 인터페이스 + 팩터리 메서드(플러그인)를 활용하여 작성할 수 있다.
작동 원리
1. 분리 인터페이스 정의
2. 플러그인 작성
3. 플러그인 팩터리 연결 명령을 지정할 장소 명시 (텍스트 파일)
사용시점
런타임 환경에 따라 다른 구현이 요구되는 동작이 있는 경우 플러그인을 사용한다.
예제: ID 생성기(자바)
아래의 그림과 같이 도메인 객체에서 ID Generator를 사용하려고 할 때 런타임의 환경파일로 구현을 변경하는 예제이다.
1. 분리인터페이스, 구현체 작성
interface IdGenerator...
public Long nextId();
class OracleIdGenerator implements IdGenerator...
public OracleIdGenerator() {
this.sequence = Environment.getProperty("id.sequence");
this.datasource = Environment.getProperty("id.source");
}
class Counter implements IdGenerator...
private long count = 0;
public synchronized Long nextId() {
return new Long(count++);
}
2. 플러그인 팩토리 작성 (인터페이스-구현 매핑), 환경파일 구성
class PluginFactory...
private static Properties props = new Properties();
//static 초기화
static {
try {
String propsFile = System.getProperty("plugins"); //연결 명령을 담은 파일 위치
props.load(new FileInputStream(propsFile));
} catch (Exception ex) {
throw new ExceptionInInitializerError(ex);
}
}
public static Object getPlugin(Class iface) {
String implName = props.getProperty(iface.getName());
if (implName == null) {
throw new RuntimeException("implementation not specified for " +
iface.getName() + " in PluginFactory propeties.");
}
try {
return Class.forName(implName).newInstance();
} catch (Exception ex) {
throw new RuntimeException("factory unable to construct instance of " +
iface.getName());
}
}
테스트 환경 시스템 프로퍼티 파일
#test.properties
IdGenerator=TestIdGenerator
실무 환경 시스템 프로퍼티 파일
#prod.properties
IdGenerator=OracleIdGenerator
3. 분리 인터페이스에서 팩토리 메서드로 인스턴스 생성
interface IdGenerator...
public static final IdGenerator INSTANCE =
(IdGenerator) PluginFactory.getPlugin(IdGenerator.class);
4. 도메인에서 사용
class Customer extends DomainObject...
private Customer(String name, Long id) {
super(id);
this.name = name;
}
public Customer create(String name) {
Long newObjId = IdGenerator.INSTANCE.nextId();
Customer obj = new Customer(name, newObjId);
obj.markNew();
return obj;
}
'Design Patterns' 카테고리의 다른 글
값 객체, 금액, 레코드 집합 (1) | 2020.10.09 |
---|---|
레지스트리 패턴, 특수 사례 패턴 (0) | 2020.10.09 |
매퍼 패턴, 계층 상위 형식패턴 (0) | 2020.10.09 |
게이트웨이 패턴, 서비스 스텁 패턴 (0) | 2020.10.08 |
지연로드(Lazy Load) 패턴 (0) | 2020.10.04 |