복합 패턴은 여러 디자인 패턴을 조합해서 복잡한 시스템을 설계할 수 있도록 하는 패턴 구성 방식임.
책에서는 "오리 시뮬레이터"를 통해 다양한 패턴을 조합하여 확장 가능하고 유연한 시스템을 만들어냄.
| 사용된 패턴 | 역할 |
|---|---|
| 팩토리 패턴 | 오리 객체 생성 캡슐화 |
| 데코레이터 패턴 | 울음 횟수 세기 기능 추가 |
| 어댑터 패턴 | 거위를 오리처럼 사용 가능하게 함 |
| 컴포지트 패턴 | 오리 그룹을 하나의 오리처럼 사용 |
| 옵저버 패턴 | 오리가 울면 옵저버에게 알림 전파 |
DuckFactory)을 통해 생성 QuackCounter로 감싸서 울음 횟수 추적 GooseAdapter로 거위를 오리로 감쌈 Flock으로 묶음 Quackologist를 옵저버로 등록 simulate()를 통해 모든 오리가 울도록 함// 인터페이스
interface Quackable extends QuackObservable {
void quack();
}
// 기본 오리
class MallardDuck implements Quackable {
Observable observable = new Observable(this);
public void quack() {
System.out.println("꽥");
notifyObservers();
}
public void registerObserver(Observer observer) {
observable.registerObserver(observer);
}
public void notifyObservers() {
observable.notifyObservers();
}
}
class QuackCounter implements Quackable {
Quackable duck;
static int quackCount;
public QuackCounter(Quackable duck) {
this.duck = duck;
}
public void quack() {
duck.quack();
quackCount++;
}
public static int getQuacks() {
return quackCount;
}
public void registerObserver(Observer observer) {
duck.registerObserver(observer);
}
public void notifyObservers() {
duck.notifyObservers();
}
}
class Goose {
public void honk() {
System.out.println("끽");
}
}
class GooseAdapter implements Quackable {
Goose goose;
Observable observable = new Observable(this);
public GooseAdapter(Goose goose) {
this.goose = goose;
}
public void quack() {
goose.honk();
notifyObservers();
}
public void registerObserver(Observer observer) {
observable.registerObserver(observer);
}
public void notifyObservers() {
observable.notifyObservers();
}
}
class Flock implements Quackable {
List<Quackable> quackers = new ArrayList<>();
public void add(Quackable quacker) {
quackers.add(quacker);
}
public void quack() {
for (Quackable quacker : quackers) {
quacker.quack();
}
}
public void registerObserver(Observer observer) {
for (Quackable quacker : quackers) {
quacker.registerObserver(observer);
}
}
public void notifyObservers() {
// Flock은 직접 notify하지 않음. 각 quacker가 notify
}
}
interface Observer {
void update(QuackObservable duck);
}
interface QuackObservable {
void registerObserver(Observer observer);
void notifyObservers();
}
class Observable implements QuackObservable {
List<Observer> observers = new ArrayList<>();
QuackObservable duck;
public Observable(QuackObservable duck) {
this.duck = duck;
}
public void registerObserver(Observer observer) {
observers.add(observer);
}
public void notifyObservers() {
for (Observer observer : observers) {
observer.update(duck);
}
}
}
class Quackologist implements Observer {
public void update(QuackObservable duck) {
System.out.println("관찰자: " + duck + " 가 방금 울었음");
}
}