본문 바로가기
공부/디자인 패턴

1. Strategy Pattern (Head First Design Patterns)

by 김주현3902 2024. 10. 20.

Duck 클래스가 있다.

모든 Duck은 swim과 display 메소드를 가지지만, 어떤 덕은 fly를, 어떤 duck은 quack을 가진다.

이때, 공통 부분은 Duck 클래스에 입력한 후 각 클래스들은 이를 상속받는다.

flyable과 quackable 인터페이스를 만든 후, 각 클래스들은 필요에 따라 이를 구현한다.

 

Design Principle

Identify the aspects of your application that vary and separate them from what stays the same

애플리케이션에서 변하는 부분을 찾아내고, 변하지 않는 부분과 그들을 분리하라.

 

Program to an interface not an implementation

구현이 아닌 인터페이스를 기준으로 프로그래밍하라.

 

이제 각각 다른 fly와 quack을 사용하려고 한다.

FlyBehavior과 QuackBehavior을 여러가지 fly와 quack이 구현한다.(ex: flyWithWings)

그리고, Duck은 FlyBehavior과 QuackBehavior을 변수로 가진다.

또한, performFly와 performQuack 메소드를 각각 flyBehavior.fly(), quackBehavior.quack()으로 정의한다.

그리고 각각의 Duck 구현체들은 생성자에서 해당하는 fly와 quack 종류를 flyBehavior과 quackBehavior로 저장한다.

이렇게 하면, Duck에 fly와 quack 또한 관리가 가능하고 서로 다른 fly와 quack을 사용할 수 있다.

public abstract class Duck {
    FlyBehavior flyBehavior;
    QuackBehavior quackBehavior;

    public Duck() {}

    public abstract void display();

    public void performQuack() {
        quackBehavior.quack();
    }
    public void performFly() {
        flyBehavior.fly();

    }

    public void swim(){
        System.out.println("swimming");
    }
}

Duck 은 FlyBehavior과 QuackBehavior을 가지며 perform 메소드를 이용하여 각 경우에 맞게 quack과 fly를 수행한다.

public interface FlyBehavior {
    public void fly();
}
public class FlyWithWings implements FlyBehavior {

    @Override
    public void fly() {
        System.out.println("flying with wings!");
    }
}
public class FlyNoWay implements FlyBehavior{
    @Override
    public void fly() {
        System.out.println("Cannot fly");
    }
}

두 가지 Fly 클래스를 구현했다.

public interface QuackBehavior {
    public void quack();
}
public class Quack implements QuackBehavior {

    @Override
    public void quack() {
        System.out.println("Quack!");
    }
}
public class QuackNoWay implements QuackBehavior{
    @Override
    public void quack() {
        System.out.println("Cannot quack");
    }
}

2 가지 quack을 구현했다.

 

public class MallardDuck extends Duck {
    public MallardDuck() {
        this.quackBehavior = new Quack();
        this.flyBehavior = new FlyWithWings();
    }

    @Override
    public void display() {
        System.out.println("I am MallardDuck");
    }
}

 

public class DecoyDuck extends Duck{

    public DecoyDuck() {
        this.quackBehavior = new QuackNoWay();
        this.flyBehavior = new FlyNoWay();
    }

    @Override
    public void display() {
        System.out.println("I am Decoy duck");
    }
}

각 Duck은 종류에 맞는 quack과 fly behavior을 설정한다.

public class DuckSimulation {
    public static void main(String[] args) {
        Duck mallard = new MallardDuck();
        Duck decoy = new DecoyDuck();

        mallard.display();
        mallard.performFly();
        mallard.performQuack();

        decoy.display();
        decoy.performFly();
        decoy.performQuack();

    }
}

두 종류의 Duck을 생성한 후 perform 메소드를 실행하면 각각 다른 fly와 quack을 수행하는 것을 알 수 있다.