알고리즘군을 정의하고 캡슐화해서 각각의 알고리즘군을 수정해서 쓸 수 있게 하는 패턴
객체의 행위를 바꾸는 경우, 직접 수정하지 않고 전략이라고 부르는 캡슐화한 알고리즘을 컨텍스트(상황, 문맥, 맥락 등 어떠한 작업을 완료하는 데 필요한 모든 관련 정보) 안에서 바꿔주면서 상호 교체가 가능하게 만드는 패턴이다.
컨텍스트(변하지 않는 부분)에서 전략(변하는 부분)을 별도로 분리한다.
클라이언트로부터 알고리즘을 분리해서 독립적으로 변경이 가능하다
클라이언트가 Context에게 Strategy를 '주입(DI:Dependancy Injection)'한다.
OO 기초
- 추상화: 불필요한 정보를 생략하고 중요한 것에 중점을 두어 모델링하는 것
- 캡슐화: 외부에서의 접근을 제한하기 위해 인터페이스를 제외한 세부 정보를 은닉하는것
- 다형성: 하나의 메시지에 대해 각각의 객체가 가지고 있는 고유한 방법으로 응답할 수 있는 능력
- 상속: 상위클래스의 모든 속성과 연산을 하위클래스가 물려받는 것
디자인 원칙
- 변하는 부분과 변하지 않는 부분을 구분하고, 변하는 부분을 캡슐화한다.
- 상속보다는 구성을 활용한다.
- 구현보다는 인터페이스에 맞춰서 프로그래밍 한다.
문제: 오리 시뮬레이션 게임에 몇몇 오리에게 fly() 행위 추가
(1) 상속
(2) fly 행위를 인터페이스로 정의
(3) 행위를 인터페이스로 정의하고, 구체적인 행위를 구현하는 클래스 생성
Duck.java : 추상 클래스
public abstract class Duck {
// 행동 인터페이스 형식의 레퍼런스 변수 선언-> composition 관계
FlyBehavior flyBehavior;
QuackBehavior quackBehavior;
public Duck() { }
public abstract void display(); // 추상 메서드
// 행위를 수행할 함수 선언 - Duck에서는 구체적인 행위를 구현할 필요가 없다.
public void performFly() {
flyBehavior.fly(); // 행위를 행동 클래스에 위임
}
public void performQuack() {
quackBehavior.quack(); // 행위를 행동 클래스에 위임
}
// 동적으로 행위 지정을 위한 함수
public void SetFlyBehavior(FlyBehavior fb) {
flyBehavior = fb;
}
public void SetQuackBehavior(QuackBehavior qb) {
quackBehavior = qb;
}
public void swim() {
System.out.println("All ducks float, even decoys!");
}
}
Fly, Quack 인터페이스
public interface FlyBehavior {
public void fly();
}
public class FlyWithWings implements FlyBehavior {
public void fly() { // 구체적인 행위
System.out.println("FlyWithWings");
}
}
public interface QuackBehavior {
public void quack();
}
public class Quack implements QuackBehavior {
public void quack() { // 구체적인 행위 지정
System.out.println("quack");
}
}
MalladDuck.java
public class MallardDuck extends Duck{
public MallardDuck() {
// 행위 선언
quackBehavior = new Quack();
flyBehavior = new FlyWithWings();
}
public void display() {
System.out.println("Mallard duck");
}
}
TestDuck.java
public class TestDuck {
public static void main(String[] args) {
MallardDuck m1 = new MallardDuck();
// fly, quack 행위 수행
m1.display();
m1.performQuack();
m1.performFly();
// 동적으로 행위 지정 - 실행시간 동안 행위를 지정할 수 있다.
m1.setFlyBehavior(new FlyNoWay());
m1.performFly();
}
}