Compound Pattern

윤세영·2023년 7월 6일
0

DesignPattern

목록 보기
1/15

Compound Pattern

정의

반복적으로 생길 수 있는 일반적인 문제를 해결하기 위한 용도로 두 개 이상의 디자인패턴을 결합하여 사용하는 것이다.
또한, 여러 패턴을 같이 사용한다고 해서 compound pattern이 되는 것이 아닌, 문제를 해결하기 위한 용도로 사용하여야 한다.

시나리오

  • Duck들이 있었는데, Goose가 등장하여 자신도 Quackable이 되고 싶다고 요청
    • Adapter Pattern을 이용하여 goose를 quackable에 맞게 구현하여 goose객체의 quack()를 호출하면 자동으로 honk()가 호출된다.
  • 학자들이 quack소리의 횟수를 세고 싶다고 함
    • Decorator Pattern을 이용하여 QuackCounter decorator를 추가하였다.
  • Quack() 메소드 호출 자체는 그 decorator로 쌓여 있는 Quackable에 의해 처리되고 quack()의 호출된 횟수를 셀 수 있게 되었다.
    • QuackCounter로 decorator 되지 않은 Quackable Object 문제
  • Abstract factory pattern을 적용하여 object를 만들도록 구성한다.
    • 모든 duck과 goose, Quackable Object들을 관리하는데 무리가 생김
  • Composite Pattern을 이용하여 duck을 모아서 ducks로 관리
    • Iterator를 통하여 반복작업까지 처리할 수 있게 됨
  • Quackable에서 quack를 호출하였다는 signal을 받고 싶어함
    • Observer Pattern을 이용하여 Quackologist를 Quackable의 observer로 등록하여 signal을 받게 되었으며, signal을 돌릴 때 iterator pattern을 적용하였다.

소스코드

  • interface
//Quckable interface
public interface Quackable {
    public void quack();
}
  • Duck object
//implement Quackable interface
 public class MallardDuck implements Quackable {
     @Override
     public void quack() {
         System.out.println("Quack");
     }
 }
public class RedheadDuck implements Quackable {
     @Override
     public void quack() {
         System.out.println("quack");
     }
 }
public class RubberDuck implements Quackable{
     @Override
     public void quack() {
         System.out.println("Squeak");
     }
 }
public class DuckCall implements Quackable{
     @Override
     public void quack() {
         System.out.println("Kwak");
     }
 }
  • GooseAdapter
//goose adapter to bind Duck class
 /*
 한 class의 interface를 client에서 사용하고 하는 다른 interface로 변환한다.
 adapter를 이용하면 interface의 호환성 문제 때문에 같이 사용할 수 없는 class를 쓸 수 있다.
  */
 public class GooseAdapter implements Quackable {
 
     Goose goose;
 
     public GooseAdapter(Goose goose) {
         this.goose = goose;
     }
 
     @Override
     public void quack() {
         goose.honk();
     }
 }
  • Goose
//add goose
 public class Goose {
     public void honk() { 
         System.out.println("Honk"); 
     }
 }
  • Abstract factory pattern
 //abstract factory pattern
 //구체적인 클래스를 지정하지 않고 관련성을 갖는 객체들의 집합을 생성하거나
 //서로 독립적인 객체들의 집합을 생성할 수 있는 인터페이스를 제공한다.
 public abstract class AbstractDuckFactory {
 
     public abstract Quackable createMallardDuck();
     public abstract Quackable createRedheadDuck();
     public abstract Quackable createDuckCall();
     public abstract Quackable createRubberDuck();
 }
  • Counting duck factory
public class CountingDuckFactory extends AbstractDuckFactory{
 
     @Override
     public Quackable createMallardDuck() {
         return new QuackCounter(new MallardDuck());
     }
 
     @Override
     public Quackable createRedheadDuck() {
         return new QuackCounter(new RedheadDuck());
     }
 
     @Override
     public Quackable createDuckCall() {
         return new QuackCounter(new DuckCall());
     }
 
     @Override
     public Quackable createRubberDuck() {
         return new QuackCounter(new RubberDuck());
     }
 }
  • main
//run
 public class DuckSimulator {
 
     public static void main(String [] args) {
         DuckSimulator simulator = new DuckSimulator();
         AbstractDuckFactory duckFactory = new CountingDuckFactory();
         simulator.simulator(duckFactory);
     }
 
 
     void simulator(AbstractDuckFactory duckFactory) {
         Quackable mallardDuck = duckFactory.createMallardDuck();
         Quackable redheadDuck = duckFactory.createRedheadDuck();
         Quackable duckCall = duckFactory.createDuckCall();
         Quackable rubberDuck = duckFactory.createRubberDuck();
         Quackable gooseDuck = new GooseAdapter(new Goose());
 
         System.out.println("\nDuck Simulator");
 
         simulator(mallardDuck);
         simulator(redheadDuck);
         simulator(duckCall);
         simulator(rubberDuck);
         simulator(gooseDuck);
 
         System.out.println("The Ducks quacked " + QuackCounter.getQuacks() + " times");
     }
 
     void simulator(Quackable duck) {
         duck.quack();
     }
 }
  • 결과화면

  • UML

profile
Frontend

0개의 댓글