헤드퍼스트 디자인 패턴의 첫번째 디자인 패턴을 분석해본다.
본 문서는 본인의 개발향상과 기억의 장기화를 위해 기록해둔다.
또한 왜 이렇게 해야 되는지를 레거시 코드를 통해 알아보도록 하겠다.
아래와 같이 청둥오리/고무오리/나무오리 가 존재한다.
각각의 오리는 아래와 같은 상황이다.
package Duck;
public class Legacy_Duck {
public Legacy_Duck(String duck) {
if(duck == "청둥오리") {
display("저는 청둥오리");
quack("꽥꽥");
fly("날다");
}
else if(duck == "고무오리") {
display("저는 고무오리");
quack("삑삑");
fly("날지 못한다. XX");
}
else if(duck == "나무오리") {
display("저는 나무오리");
quack("조용");
fly("날지 못한다.");
}
}
public void swim() {
System.out.println("수영하다.");
}
public void quack(String q) {
System.out.println(q);
}
public void fly(String s) {
System.out.println(s);
}
public void display(String d) {
System.out.println(d);
}
}
실행코드
package Duck;
public class Legacy_Example {
public static void main(String[] args) {
Legacy_Duck duck = new Legacy_Duck("고무오리");
}
}
저는 고무오리
삑삑
날지 못한다. XX
package Duck;
public class Legacy_Example {
public static void main(String[] args) {
Legacy_Duck duck = new Legacy_Duck("청둥오리");
}
}
저는 청둥오리
꽥꽥
날다
위 레거시 코드를 전략패턴으로 바꿔보자
변경되는 부분을 인터페이스로 구현한다.
- 소리내다 (quack) : 꽥꽥, 삑삑, 조용
- 날다 (fly) : 날다, 날지못한다. 엄청빠르게 로켓같이 날다.
인터페이스를 분리 했으면 오리 객체를 만들어 보겠다.
package Duck;
public abstract class Duck {
IFlyBehavior iflyBehavior;
IQuackBehavior iquackBehavior;
public Duck() {}
public abstract void disply();
public void performFlay() {
iflyBehavior.fly();
}
public void performQuack() {
iquackBehavior.quack();
}
public void swim() {
System.out.println("모든오리 물에 뜬다. 가짜오리도 뜬다.");
}
public void setFlyBehavior(IFlyBehavior fb) {
iflyBehavior = fb;
}
public void setQuackBehavior(IQuackBehavior qb) {
iquackBehavior = qb;
}
}
추상화 오리객체
- 두개의 인터페이스
- 추상화된 display()
- 인터페이스 를 통한 날다. performFly()
- 인터페이스 를 통한 꽥꽥. performQuack()
오리객체 는 아래 객체에서 상속받습니다.
- 청둥오리
- 모형오리
- 고무오리
package Duck;
//청둥오리
public class MallardDuck extends Duck{
public MallardDuck() {
iquackBehavior = new Quack();
iflyBehavior = new FlyWithWings();
}
@Override
public void display() {
System.out.println("저는 청둥오리 입니다.");
}
}
package Duck;
public class ModelDuck extends Duck{
public ModelDuck() {
iflyBehavior = new FlyNoWay();
iquackBehavior = new Quack();
}
@Override
public void display() {
System.out.println("저는 모형오리 입니다.");
}
}
package Duck;
//고무오리
public class RubberDuck extends Duck{
public RubberDuck() {
iquackBehavior = new Squeak();
iflyBehavior = new FlyNoWay();
}
@Override
public void display() {
System.out.println("저는 고무오리 입니다.");
}
}
실행기
package Duck;
public class MiniDuckSimulator {
public static void main(String[] args) {
Duck mallard = new MallardDuck();
mallard.display();
mallard.performQuack();
mallard.performFly();
System.out.println("-------------------");
Duck rubber = new RubberDuck();
rubber.display();
rubber.performQuack();
rubber.performFly();
System.out.println("-------------------");
Duck model = new ModelDuck();
model.display();
model.performFly();
model.setFlyBehavior(new FlyRocketPowered());
model.performFly();
}
}
결과
저는 청둥오리 입니다.
꽥꽥
날고 있어요~~
-------------------
저는 고무오리 입니다.
삑삑
저는 못날아요
-------------------
저는 모형오리 입니다.
저는 못날아요
로켓 추진으로 날아갑니다.
우리는 위와 같이 전략패턴을 사용하여 if문을 제거할수 있다.
최종 목표는 if문을 제거할수 있는 방법을 배우는 것이다.
JS버전
레거시 코드
let duck = '청둥오리';
const display = m => console.log('나는 '+m+' 입니다.');
const fly = m => console.log(m);
const quack = m => console.log(m);
if(duck == '청둥오리') {
display('청둥오리');
fly('날다');
quack('꽥꽥');
} else if(duck == '고무오리') {
display('고무오리');
fly('날지못한다.');
quack('조용');
} else if(duck == '모형오리') {
display('모형오리');
fly('날지못한다.');
quack('삑삑');
}
나는 청둥오리 입니다.
날다
꽥꽥
'객체지향' 카테고리의 다른 글
템플릿 메소드(Template Method) 패턴 실제 적용 사례 - 디자인 패턴 (0) | 2024.08.23 |
---|---|
[ES6] 템플릿 메소드 패턴 예제 (0) | 2022.05.09 |
객체지향 디자인 패턴 공부 순서 (0) | 2020.08.31 |
OOP Interface 를 왜 사용하는가 ? (0) | 2020.07.27 |