어떤 작업을 처리하는 일부분을 서브 클래스로 캡슐화해 전체 일을 수행하는 구조는 바꾸지 않으면서 특정 단계에서 수행하는 내역을 바꾸는 패턴으로, 전체적으로는 동일하면서 부분적으로는 다른 구문으로 구성된 메서드의 코드 중복을 최소화 할 때 유용하다.
커피와 홍차 만드는 법이 다음과 같다고 가정하자.
위 프로세스는 전반적인 순서는 동일하지만, 세부 구현사항은 다르다. 또한 완벽히 일치하는 프로세스 또한 존재한다.
만약 이를 인터페이스로 프로세스를 추상화한다면 일부 중복 코드(물을 끓인다)가 발생한다.
상속으로 중복코드를 제거하려고 하면 불필요한 메서드 혹은 상태의 상속이 일어날 수 있다.
공통적인 인터페이스는 추상화하고, 중복 코드는 통일시켜 구현한다.
abstract class Beverage {
public void order() {
boilWater();
brew();
pourInCup();
addCondiments();
}
protected void boilWater() { ... }
protected void pourInCup() { ... }
abstract protected void brew();
abstract protected void addCondiments();
}
각 타입에 따른 차이점을 별도로 구현한다.
class Tee extends Beverage {
@Override
protected void brew() {
// 찻잎을 우려냅니다.
}
@Override
protected void addCondiments() {
// 레몬을 추가합니다.
}
}
```java
class Coffe extends Beverage {
@Override
protected void brew() {
// 커피를 우려냅니다.
}
@Override
protected void addCondiments() {
// 설탕과 우유를 추가합니다.
}
}