이번 포스트팅은 디자인 패턴중 전략 패턴을 적용해보고 실습해 보자.
비슷한 기능(알고리즘)을 수행하는 경우, 캡슐화하여 클라이언트로부터 분리를 통해 코드를 변경을 하거나 기능을 확장을 용이하게 해준다.
중요한 것은 변하는 기능을 독립적으로 캡슐화하는 것이다. 상속보단 구현(인터페이스)을 사용한다.
public interface FlyBehavior {
public void fly();
}
public class HighFly implements FlyBehavior {
@Override
public void fly() {
System.out.println("높게 날아요");
}
}
public class LowFly implements FlyBehavior {
@Override
public void fly() {
System.out.println("낮게 날아요");
}
}
public class NoFly implements FlyBehavior {
@Override
public void fly() {
System.out.println("못 날아요");
}
}
public interface QuackBehavior {
public void quack();
}
public class NoQuack implements QuackBehavior {
@Override
public void quack() {
System.out.println("조용");
}
}
public class BigQuack implements QuackBehavior {
@Override
public void quack() {
System.out.println("크게 꽥");
}
}
public class SmallQuack implements QuackBehavior {
@Override
public void quack() {
System.out.println("작게 꽥");
}
}
public abstract class Duck {
protected FlyBehavior flyBehavior;
protected QuackBehavior quackBehavior;
// 인터페이스 타입을 DI한다.
public Duck(FlyBehavior flyBehavior, QuackBehavior quackBehavior) {
this.flyBehavior = flyBehavior;
this.quackBehavior = quackBehavior;
}
//오리가 소리를 내는 것을 quackBehavior에 위임한다.
public void doQuack() {
quackBehavior.quack();
}
//오리가 나는 것을 flyBehavior에 위임한다.
public void doFly() {
flyBehavior.fly();
}
//오리가 다친다.
public boolean injured() {
System.out.println("날개 부상");
return true;
}
//오리가 다칠 경우 나는 행동을 바꾼다.
public void setFly(FlyBehavior flyBehavior) {
this.flyBehavior = flyBehavior;
}
public void setQuack(QuackBehavior quackBehavior) {
this.quackBehavior = quackBehavior;
}
public abstract void display();
}
public class Duck1 extends Duck {
public Duck1(FlyBehavior flyBehavior, QuackBehavior quackBehavior) {
super(flyBehavior, quackBehavior);
}
@Override
public void display() {
System.out.println("오리 1입니다.");
}
}
public class Duck2 extends Duck{
public Duck2(FlyBehavior flyBehavior, QuackBehavior quackBehavior) {
super(flyBehavior, quackBehavior);
}
@Override
public void display() {
System.out.println("오리 2");
}
}
public class Duck3 extends Duck {
public Duck3(FlyBehavior flyBehavior, QuackBehavior quackBehavior) {
super(flyBehavior, quackBehavior);
}
@Override
public void display() {
System.out.println("오리 3입니다.");
}
}
// Duck을 생성하면서 구체적인 클래스들을 주입한다.
Duck duck1 = new Duck1(new HighFly(), new BigQuack());
Duck duck2 = new Duck2(new LowFly(), new SmallQuack());
Duck duck3 = new Duck3(new NoFly(), new NoQuack());
duck1.display();
duck1.doQuack();
duck1.doFly();
System.out.println("================");
duck2.display();
duck2.doQuack();
duck2.doFly();
System.out.println("================");
duck3.display();
duck3.doQuack();
duck3.doFly();
public class MiddleFly implements FlyBehavior{
@Override
public void fly() {
System.out.println("중간 높이로 난다.");
}
}
// Duck을 생성하면서 구체적인 클래스들을 주입한다.
Duck duck1 = new Duck1(new HighFly(), new BigQuack());
Duck duck2 = new Duck2(new LowFly(), new SmallQuack());
Duck duck3 = new Duck3(new NoFly(), new NoQuack());
duck1.display();
duck1.doQuack();
duck1.doFly();
System.out.println("================");
duck2.display();
duck2.doQuack();
duck2.doFly();
System.out.println("================");
duck3.display();
duck3.doQuack();
duck3.doFly();
System.out.println("=====런 타임 변경======");
//만약 오리가 다치면 fly 특성을 바꿔 줄 수 있다.
if (duck1.injured()) {
duck1.setFly(new MiddleFly());
duck1.display();
duck1.doFly();
}
//결과
오리 1입니다.
크게 꽥
높게 날아요
================
오리 2
작게 꽥
낮게 날아요
================
오리 3입니다.
조용
못 날아요
=====런 타임 변경======
날개 부상
오리 1입니다.
중간 높이로 날아요.
Reference