/ DESIGN-PATTERNS

Strategy Pattern(스트레티지 패턴)

스테리티지 패턴

  • 자주 변하는 부분을 캡슐화 하여,코드의 유연성을 높인다.

시나리오

Head First 디자인패턴 참조 p.40~p.43




1.오리 클래스

잘 돌아가고 있는 오리에 대한 클레스와 , 자식들



public class Duck {
    void quack(){
        System.out.printf("꽥!");
    }
    void swim(){
        System.out.printf("수영하는 오리");
    }
    void display(){
        System.out.printf("저는 오리입니다.");
    }
}

//고무오리
class RubberDuck extends Duck{
    @Override
    void display() {
        System.out.printf("저는 고무오리 입니다.");
    }
}

//청둥오리
class MallardDuck extends Duck{
    @Override
    void display() {
        System.out.printf("저는 청둥오리 입니다.");
    }
}




2.고객의 기능 추가요청

고객 : 오리가 날수있으면 좋겠어요 :)

프로그래머 : 음, 최상위 클래스인 Duck 에 나는 기능을 추가하면 자식들도 다같이 날수 있겠군.. 알겠습니다.

public class Duck {

   //1. add fly method
   void fly(){
        System.out.printf("저이제 날수있어요.");
   }

}




3. 예상치 못한 상속의 부작용

고객: 러버덕은 장난감 인데요?.. 어떻게 날수있는거죠?

프로그래머: …

//고무오리
class RubberDcuk extends Duck{ 

   //상속받은 Duck에 있는 fly method가 실행됩니다.
}




4. 아! 인터페이스가 있었지

프로그래머: Flyable 인터페이스를 구현하고, 날수 있는 애들만 구현시키자!

interface Flyable{
    void fly();
}
//청둥오리
                                                   //구현 했어요!
class MallardDuck extends Duck implements Flyable{
   //...기존코드(생략)

    @Override
    public void fly() {
        System.out.printf("저는 날수 있어요");
    }
}

//고무오리(저는 날 필요가 없기에 구현 안했어요.)
class RubberDuck extends Duck{
   //...기존코드(생략)
}




5.더 많은 자식 객체(오리)들이 있다면?..

시니어 : 아 MallardDuck 말고도 RedheadDuck, 가창오리 고방오리 발구지 비오리 원앙 청둥오리 점무늬오리 혹부리오리등등이 더있고, 앞으로 더 추가할 예정이요

프로그래머: 아 기존에 Duck을 상속받은 자식객체가 50개가 넘게있군요



프로그래머: 흠.. 기존 50개의 클래스들에 implements를 하나씩 수정하는건 좀 귀찮은데 다른 방법이 없을까.. 그리고 앞으로 생길 오리들을 위해서라도..




6.스트레티지 패턴이 있습니다!

사용법

  • 변하는 부분 묶기(날기, 꽥 거리기)
    나무오리는 꽥 거리지 못하고 못날고, 러버덕은 누르면 꽥!소리는 내는데 날지못하니깐..
  • 변하지 않는 부분 묶기(display 메소드)

a. 변하는 부분 인터페이스 만들어주기

이부분은 인터페이스로 선언해줍니다.(4번이랑 똑같다고요? 좀더 지켜봐주세요)

 interface FlyBehavior {
    void fly();
}

interface  QuackBehavior{
    void quack();
}




b.상속받은 인터페이스의 구현클레스들 만들기

class FlyWithWing implements FlyBehavior{
    @Override
    public void fly() {
        System.out.printf("저 날고 있어요"); 
    }
}
class FlyNoWay implements FlyBehavior{
    @Override
    public void fly() {
        System.out.printf("저는 못날아요");
    }
}
class Quack implements QuackBehavior{
    @Override
    public void quack() {
        System.out.printf("꽥!");
    }
}
class Squeak implements QuackBehavior{
    @Override
    public void quack() {
        //고무오리 소리
        System.out.printf("삑삑!");
    }
}
class MuteQuack implements QuackBehavior{
    @Override
    public void quack() {
        System.out.printf("아무 소리도 안남");
    }
}




c. 인터페이스를 Duck 안에 넣기


public class Duck {

    //변하는 부분
    FlyBehavior flyBehavior;
    QuackBehavior quackBehavior;

   //구현 클레스에 행동 위임
   public void performFly(){
        flyBehavior.fly();
    }
    
    public void performQuack(){
        quackBehavior.quack();
    }

    //변하지 않는 부분
    void swim(){
        System.out.printf("수영하는 오리");
    }
    void display(){
        System.out.printf("저는 오리입니다.");
    }
}




d.자식들 구현부분

class MallardDuck extends Duck{

   //생성자로 행동들 연결해주기
    public MallardDuck() {
        quackBehavior = new Quack();
        flyBehavior = new FlyWithWing();
    }
}

디자인 패턴 목록