책에서 공부한 내용들을 활용해 복합 패턴으로 하나의 프로그램을 만들어보자.
public interface Quackable {
public void quack();
}
먼저 위와 같은 기본적인 인터페이스가 있고
public class Duck implements Quackable {
public void quack() {
...
}
}
그 인터페이스를 implements 받아 오리 객체를 만드는 클래스가 존재한다.
Adapter Pattern
그런데 여기서 오리가 아닌 거위 객체가 추가 되었다.
public class Goose {
public void honk() {
...
}
}
거위는 quack이 아닌 honk 메소드를 가지고 있다.
여기서 어댑터 패턴을 사용한다.
public class GooseAdapter implements Quackable {
...
public void quack() {
goose.honk();
}
public String toString() {
return "Goose pretending to be a Duck";
}
}
quack() 메소드가 호출되면 honk() 메소드를 호출하게끔 만들었다.
Decorate Pattern
오리가 우는 소리를 추가해보자.
public class DuckSimulator {
public static void main(String[] args) {
Quackable mallardDuck = new QuackCounter(new MallardDuck());
mallardDuck.quack(); // '꽥꽥'이 출력되며 numberOfQuacks += 1
}
}
public class QuackCounter implements Quackable {
...
public void quack() {
duck.quack();
numberOfQuacks++;
}
public static int getQuacks() {
return numberOfQuacks;
// toString
}
QuackCounter로 감싼 객체는 ~Duck 클래스 안의 quack() 메소드가 아닌, QuackCounter 클래스 안의 quack() 메소드가 실행된다.
Factory Pattern
오리의 객체를 생성하는 작업을 따로 한 군데에 몰아 넣어보자.
public class CountingDuckFactory extends AbstractDuckFactory {
public Quackable createMallardDuck() {
return new QuackCounter(new MallardDuck());
}
...
}
데코레이터로 감싼 오리 객체를 return 해주는 CountingDuckFactory 클래스를 만들었다.
아래에서 실행할 시뮬레이터는 실제 어떤 객체가 만들어지는지 알 수 없다.
그냥 Quackable이 return 된다는 사실만 알 수 있다.
public class DuckSimulator {
public static void main(String[] args) {
DuckSimulator simulator = new DuckSimulator();
AbstractDuckFactory duckFactory = new CountingDuckFactory();
simulator.simulate(duckFactory);
}
void simulate(AbstractDuckFactory duckFactory) {
Quackable mallardDuck = duckFactory.createMallardDuck();
... // 나머지 오리 객체들 전부 생성
mallardDuck.quack();
System.out.println("The ducks quacked " +
QuackCounter.getQuacks() + // getQuacks() 메소드가 static으로 설정되어 있어서 호출 가능
" times");
}
}
Compostie Pattern
오리의 종류가 지금보다 더 많아지면 관리가 힘들어질 것이다.
종 별로 관리할 수 있도록 Composite Pattern을 적용해보자.
import java.util.Iterator;
import java.util.ArrayList;
public class Flock implements Quackable {
ArrayList<Quackable> quackers = new ArrayList<Quackable>(); // 오리 객체를 저장할 ArrayList
public void add(Quackable quacker) { // 생성된 오리 객체를 ArrayList에 저장하는 메소드
quackers.add(quacker);
}
// ArrayList를 순환하며 모든 오리의 quack() 메소드를 호출한다.
public void quack() {
Iterator<Quackable> iterator = quackers.iterator();
while (iterator.hasNext()) {
Quackable quacker = iterator.next();
quacker.quack();
}
}
}
오리를 한 번에 모아서 관리하기 위한 Flock 클래스를 만들었다.
public class DuckSimulator {
public static void main(String[] args) {
DuckSimulator simulator = new DuckSimulator();
AbstractDuckFactory duckFactory = new CountingDuckFactory();
simulator.simulate(duckFactory);
}
void simulate(AbstractDuckFactory duckFactory) {
// 오리 객체 생성
Quackable redheadDuck = duckFactory.createRedheadDuck();
Quackable duckCall = duckFactory.createDuckCall();
Quackable rubberDuck = duckFactory.createRubberDuck();
Quackable gooseDuck = new GooseAdapter(new Goose());
Flock flockOfDucks = new Flock();
// Flock(군단)에 생성된 오리들 추가 -> 묶어서 관리하기 위함
flockOfDucks.add(redheadDuck);
flockOfDucks.add(duckCall);
flockOfDucks.add(rubberDuck);
flockOfDucks.add(gooseDuck);
System.out.println("\nDuck Simulator: Whole Flock Simulation");
simulate(flockOfDucks);
System.out.println("\nThe ducks quacked " +
QuackCounter.getQuacks() +
" times");
}
void simulate(Quackable duck) {
duck.quack();
}
}
이렇게 오리는 오리 종류끼리 묶어서 관리할 수 있다.
만약 그냥 Duck이 아닌 MallDuck 객체가 추가 된다면,
Flock flockOfMallards = new Flock();
flockOfMallards.add(mallardOne);
flockOfMallards.add(mallardTwo);
이런 식으로 묶어서 관리하면 된다.
'Design Pattern' 카테고리의 다른 글
[Headfirst Design Pattern] 템플릿 메소드 패턴(Template Method Pattern) (0) | 2024.06.06 |
---|---|
[Headfirst Design Parttern] 어댑터 패턴&퍼사드 패턴(Adapter Pattern & Facade Pattern) (0) | 2024.06.05 |
[Headfirst Design Pattern] 데코레이터 패턴(Decorator Pattern) (2) | 2024.04.24 |
[Headfirst Design Pattern] 옵저버 패턴(Observer Pattern) (0) | 2024.04.12 |
책에서 공부한 내용들을 활용해 복합 패턴으로 하나의 프로그램을 만들어보자.
public interface Quackable {
public void quack();
}
먼저 위와 같은 기본적인 인터페이스가 있고
public class Duck implements Quackable {
public void quack() {
...
}
}
그 인터페이스를 implements 받아 오리 객체를 만드는 클래스가 존재한다.
Adapter Pattern
그런데 여기서 오리가 아닌 거위 객체가 추가 되었다.
public class Goose {
public void honk() {
...
}
}
거위는 quack이 아닌 honk 메소드를 가지고 있다.
여기서 어댑터 패턴을 사용한다.
public class GooseAdapter implements Quackable {
...
public void quack() {
goose.honk();
}
public String toString() {
return "Goose pretending to be a Duck";
}
}
quack() 메소드가 호출되면 honk() 메소드를 호출하게끔 만들었다.
Decorate Pattern
오리가 우는 소리를 추가해보자.
public class DuckSimulator {
public static void main(String[] args) {
Quackable mallardDuck = new QuackCounter(new MallardDuck());
mallardDuck.quack(); // '꽥꽥'이 출력되며 numberOfQuacks += 1
}
}
public class QuackCounter implements Quackable {
...
public void quack() {
duck.quack();
numberOfQuacks++;
}
public static int getQuacks() {
return numberOfQuacks;
// toString
}
QuackCounter로 감싼 객체는 ~Duck 클래스 안의 quack() 메소드가 아닌, QuackCounter 클래스 안의 quack() 메소드가 실행된다.
Factory Pattern
오리의 객체를 생성하는 작업을 따로 한 군데에 몰아 넣어보자.
public class CountingDuckFactory extends AbstractDuckFactory {
public Quackable createMallardDuck() {
return new QuackCounter(new MallardDuck());
}
...
}
데코레이터로 감싼 오리 객체를 return 해주는 CountingDuckFactory 클래스를 만들었다.
아래에서 실행할 시뮬레이터는 실제 어떤 객체가 만들어지는지 알 수 없다.
그냥 Quackable이 return 된다는 사실만 알 수 있다.
public class DuckSimulator {
public static void main(String[] args) {
DuckSimulator simulator = new DuckSimulator();
AbstractDuckFactory duckFactory = new CountingDuckFactory();
simulator.simulate(duckFactory);
}
void simulate(AbstractDuckFactory duckFactory) {
Quackable mallardDuck = duckFactory.createMallardDuck();
... // 나머지 오리 객체들 전부 생성
mallardDuck.quack();
System.out.println("The ducks quacked " +
QuackCounter.getQuacks() + // getQuacks() 메소드가 static으로 설정되어 있어서 호출 가능
" times");
}
}
Compostie Pattern
오리의 종류가 지금보다 더 많아지면 관리가 힘들어질 것이다.
종 별로 관리할 수 있도록 Composite Pattern을 적용해보자.
import java.util.Iterator;
import java.util.ArrayList;
public class Flock implements Quackable {
ArrayList<Quackable> quackers = new ArrayList<Quackable>(); // 오리 객체를 저장할 ArrayList
public void add(Quackable quacker) { // 생성된 오리 객체를 ArrayList에 저장하는 메소드
quackers.add(quacker);
}
// ArrayList를 순환하며 모든 오리의 quack() 메소드를 호출한다.
public void quack() {
Iterator<Quackable> iterator = quackers.iterator();
while (iterator.hasNext()) {
Quackable quacker = iterator.next();
quacker.quack();
}
}
}
오리를 한 번에 모아서 관리하기 위한 Flock 클래스를 만들었다.
public class DuckSimulator {
public static void main(String[] args) {
DuckSimulator simulator = new DuckSimulator();
AbstractDuckFactory duckFactory = new CountingDuckFactory();
simulator.simulate(duckFactory);
}
void simulate(AbstractDuckFactory duckFactory) {
// 오리 객체 생성
Quackable redheadDuck = duckFactory.createRedheadDuck();
Quackable duckCall = duckFactory.createDuckCall();
Quackable rubberDuck = duckFactory.createRubberDuck();
Quackable gooseDuck = new GooseAdapter(new Goose());
Flock flockOfDucks = new Flock();
// Flock(군단)에 생성된 오리들 추가 -> 묶어서 관리하기 위함
flockOfDucks.add(redheadDuck);
flockOfDucks.add(duckCall);
flockOfDucks.add(rubberDuck);
flockOfDucks.add(gooseDuck);
System.out.println("\nDuck Simulator: Whole Flock Simulation");
simulate(flockOfDucks);
System.out.println("\nThe ducks quacked " +
QuackCounter.getQuacks() +
" times");
}
void simulate(Quackable duck) {
duck.quack();
}
}
이렇게 오리는 오리 종류끼리 묶어서 관리할 수 있다.
만약 그냥 Duck이 아닌 MallDuck 객체가 추가 된다면,
Flock flockOfMallards = new Flock();
flockOfMallards.add(mallardOne);
flockOfMallards.add(mallardTwo);
이런 식으로 묶어서 관리하면 된다.
'Design Pattern' 카테고리의 다른 글
[Headfirst Design Pattern] 템플릿 메소드 패턴(Template Method Pattern) (0) | 2024.06.06 |
---|---|
[Headfirst Design Parttern] 어댑터 패턴&퍼사드 패턴(Adapter Pattern & Facade Pattern) (0) | 2024.06.05 |
[Headfirst Design Pattern] 데코레이터 패턴(Decorator Pattern) (2) | 2024.04.24 |
[Headfirst Design Pattern] 옵저버 패턴(Observer Pattern) (0) | 2024.04.12 |