객체지향

[헤드퍼스트 디자인패턴] 1. 전략패턴

소행성왕자 2022. 3. 29. 09:50

헤드퍼스트 디자인 패턴의 첫번째 디자인 패턴을 분석해본다.

본 문서는 본인의 개발향상과 기억의 장기화를 위해 기록해둔다.

또한 왜 이렇게 해야 되는지를 레거시 코드를 통해 알아보도록 하겠다.

아래와 같이 청둥오리/고무오리/나무오리 가 존재한다.

각각의 오리는 아래와 같은 상황이다.

package Duck;

public class Legacy_Duck {

    public Legacy_Duck(String duck) {
        if(duck == "청둥오리") {
            display("저는 청둥오리");
            quack("꽥꽥");
            fly("날다");

        }
        else if(duck == "고무오리") {
            display("저는 고무오리");
            quack("삑삑");
            fly("날지 못한다. XX");
        }
        else if(duck == "나무오리") {
            display("저는 나무오리");
            quack("조용");
            fly("날지 못한다.");
        }

    }
    public void swim() {
        System.out.println("수영하다.");
    }
    public void quack(String q) {
        System.out.println(q);
    }
    public void fly(String s) {
        System.out.println(s);
    }
    public void display(String d) {
        System.out.println(d);
    }
}

실행코드

package Duck;

public class Legacy_Example {

    public static void main(String[] args) {
        Legacy_Duck duck = new Legacy_Duck("고무오리");

    }
}

저는 고무오리
삑삑
날지 못한다. XX
package Duck;

public class Legacy_Example {

    public static void main(String[] args) {
        Legacy_Duck duck = new Legacy_Duck("청둥오리");

    }
}

저는 청둥오리
꽥꽥
날다

위 레거시 코드를 전략패턴으로 바꿔보자

변경되는 부분을  인터페이스로 구현한다.

인터페이스

  • 소리내다  (quack) : 꽥꽥, 삑삑, 조용
  • 날다  (fly) : 날다, 날지못한다. 엄청빠르게 로켓같이 날다.

인터페이스를 분리 했으면 오리 객체를 만들어 보겠다.

package Duck;

public abstract class Duck {
    IFlyBehavior iflyBehavior;
    IQuackBehavior iquackBehavior;

    public Duck() {}
    public abstract void disply();
    public void performFlay() {
        iflyBehavior.fly();
    }
    public void performQuack() {
        iquackBehavior.quack();
    }
    public void swim() {
        System.out.println("모든오리 물에 뜬다. 가짜오리도 뜬다.");
    }

    public void setFlyBehavior(IFlyBehavior fb) {
        iflyBehavior = fb;
    }
    public void setQuackBehavior(IQuackBehavior qb) {
        iquackBehavior = qb;
    }
}

추상화 오리객체 

  • 두개의 인터페이스
  • 추상화된 display()
  • 인터페이스 를 통한 날다. performFly()
  • 인터페이스 를 통한 꽥꽥. performQuack()

오리객체 는 아래 객체에서 상속받습니다.

  • 청둥오리
  • 모형오리
  • 고무오리
package Duck;

//청둥오리
public class MallardDuck extends Duck{

    public MallardDuck() {
        iquackBehavior = new Quack();
        iflyBehavior = new FlyWithWings();
    }

    @Override
    public void display() {
        System.out.println("저는 청둥오리 입니다.");
    }
}
package Duck;

public class ModelDuck extends Duck{

    public ModelDuck() {
        iflyBehavior = new FlyNoWay();
        iquackBehavior = new Quack();
    }

    @Override
    public void display() {
        System.out.println("저는 모형오리 입니다.");
    }
}
package Duck;

//고무오리
public class RubberDuck extends Duck{

    public RubberDuck() {
        iquackBehavior = new Squeak();
        iflyBehavior = new FlyNoWay();
    }

    @Override
    public void display() {
        System.out.println("저는 고무오리 입니다.");
    }
}

실행기

package Duck;

public class MiniDuckSimulator {
    public static void main(String[] args) {

        Duck mallard = new MallardDuck();
        mallard.display();
        mallard.performQuack();
        mallard.performFly();

        System.out.println("-------------------");

        Duck rubber = new RubberDuck();
        rubber.display();
        rubber.performQuack();
        rubber.performFly();

        System.out.println("-------------------");

        Duck model = new ModelDuck();
        model.display();
        model.performFly();
        model.setFlyBehavior(new FlyRocketPowered());
        model.performFly();

    }
}

결과

저는 청둥오리 입니다.
꽥꽥
날고 있어요~~
-------------------
저는 고무오리 입니다.
삑삑
저는 못날아요
-------------------
저는 모형오리 입니다.
저는 못날아요
로켓 추진으로 날아갑니다.

우리는 위와 같이 전략패턴을 사용하여 if문을 제거할수 있다.

최종 목표는 if문을 제거할수 있는 방법을 배우는 것이다.


JS버전

레거시 코드

let duck = '청둥오리';

const display = m => console.log('나는 '+m+' 입니다.');
const fly = m => console.log(m);
const quack = m => console.log(m);

if(duck == '청둥오리') {

    display('청둥오리');
    fly('날다');
    quack('꽥꽥');

} else if(duck == '고무오리') {
    display('고무오리');
    fly('날지못한다.');
    quack('조용');
} else if(duck == '모형오리') {
    display('모형오리');
    fly('날지못한다.');
    quack('삑삑');
}


나는 청둥오리 입니다.
날다
꽥꽥