디자인 패턴

전략 패턴 ( Strategy Pattern )

그zi운아이 2023. 10. 18. 21:27

전략 패턴이란?

  • 전략 패턴은 알고리즘군을 정의하고 캡슐화해서 각각의 알고리즘군을 수정해서 쓸 수 있게 해 줍니다.
  • 전략 패턴을 사용하면 클라이언트로부터 알고리즘을 분리해서 독립적으로 변경할 수 있습니다.

 

오리를 구현다고 생각해보자 우선 장난감 오리, 청둥오리, 원앙등 오리마다 우는 소리가 다를다 이 때 여러 방법을 사용해서 구현이 가능하다.

첫번째로 if - else 를 사용할수 있다. 

 

1. IF -Else

class Duck {
    String type;

    public Duck(String type) {
        this.type = type;
    }

    public void quack() {
        if ("RealDuck".equals(type)) {
            System.out.println("Quack Quack!");
        } else if ("ToyDuck".equals(type)) {
            System.out.println("Squeak!");
        }
    }
}

public class Main {
    public static void main(String[] args) {
        Duck realDuck = new Duck("RealDuck");
        Duck toyDuck = new Duck("ToyDuck");
        
        realDuck.quack(); // Output: Quack Quack!
        toyDuck.quack();  // Output: Squeak!
    }
}

위 같이 구현하면 단순하다는 장점이 있지만 새로운 오리가 추가될 때마다 quuack()메소드를 수정해야하고 이는 Open-Closed원칙에 위배된다. 다음 방법으로는 상속을 이용한 구현을 생각할 수 있다.

 

2.상속

class Duck {
    public void quack() {
        System.out.println("Quack Quack!");
    }
}

class ToyDuck extends Duck {
    @Override
    public void quack() {
        System.out.println("Squeak!");
    }
}

public class Main {
    public static void main(String[] args) {
        Duck realDuck = new Duck();
        Duck toyDuck = new ToyDuck();
        
        realDuck.quack();
        toyDuck.quack();  
    }
}

상속을 통한 구현으로 재사용이 가능해졌지만 하위 클래스가 상위 클래스에 강하게 의지하는 구조를 가지고 있다. 만역 상위 클래스에 변경이 생기면 하위 클레스가 영향을 받을수 있다는 단점이 있다. 바뀌는 부분을 캡슐화하여 해당 부분이 클래스 구조에 영향을 하지 않도록 하는 전략 패턴을 사용하여 구현할 수 있다.

 

3.전략 패턴

           +--------------+
           |    Duck      |
           +--------------+
           | display()    |
           | setQuackBehavior(QuackBehavior) |
           | quack()      |
           +------+-------+
                  |
        +---------+--------+
        |                  |
+-------+-------+  +--------+-------+
| RealDuck       |  | ToyDuck        |
+----------------+  +----------------+
| setQuackBehavior(new Quack()) |  | setQuackBehavior(new Squeak()) |
+----------------+  +----------------+

+-------------------+
|   QuackBehavior   |
+-------------------+
| quack()           |
+--------+----------+
         |
  +------+------+
  |             |
+--------+    +---------+
| Quack  |    | Squeak  |
+--------+    +---------+
interface QuackBehavior {
    void quack();
}

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

class Squeak implements QuackBehavior {
    public void quack() {
        System.out.println("Squeak!");
    }
}

class Duck {
    QuackBehavior quackBehavior;
    
    public Duck(QuackBehavior quackBehavior) {
        this.quackBehavior = quackBehavior;
    }

    public void quack() {
        quackBehavior.quack();
    }
}

public class Main {
    public static void main(String[] args) {
        Duck realDuck = new Duck(new Quack());
        Duck toyDuck = new Duck(new Squeak());
        
        realDuck.quack(); // Output: Quack Quack!
        toyDuck.quack();  // Output: Squeak!
    }
}

위 코드를 이용하여 Duck클래스의 quack() 메서드의 동작을 동적으로 변경할수 있게 되었다.

울음 소리를 추가하기 위해서는 QuackBeavior를 구현한 새 클래스를 만들면 되어 Duck클래스를 수정할 필요가 없다 OPC를 지키며 개발 가능

QuackBehavio 인터페이스를 구현한 클래스 내부에 캡술화 되어 있어, 재사용이 쉬워진다.

 

'디자인 패턴' 카테고리의 다른 글

어댑터 패턴과 퍼사드 패턴  (0) 2023.11.24