디자인패턴
-
- 스트래티지 패턴(Strategy pattern)
-
스트래티지 패턴(Strategy pattern)에서는 알고리즘군을 정의하고 각각을 캡슐화하여 교환해서 사용할 수 있도록 만든다. 스트래티지를 활용하면 알고리즘을 사용하는 클라이언트와는 독립적으로 알고리즘을 변경할 수 있다.
-
여러 오리들의 특성을 정의한 클래스들을 만든다.(이클립스 UML 설치http://all-record.tistory.com/128)
: 오리의 기본 특성(quack꽥꽥, swim수영, display보여주기)을 가진 Duck클래스와 Duck을 상속받은 개별 오리들, display override
-
다음 중 Duck의 행동을 제공하는 데 있어서 상속을 사용할 때 단점이 될 수 있는 것을 모두 고르시오. (정답. A, B, G, E) A. 서브클래스에서 코드가 중복된다. B. 실행시에 특징을 바꾸기 힘들다. C. 오리가 춤추게 만들 수 없다. D. 모든 오리의 행동을 알기 힘들다. E. 오리가 날면서 동시에 꽥꽥거릴 수 없다. F. 코드를 변경했을 때 다른 오리들한테 원치 않은 영향을 끼칠 수 있다.
-
오리가 만약 날아야 한다면?
- : Duck에 fly메서드를 추가? -> 서브클래스 오리 모두 날 수 있다.
-
Duck에 아무것도 하지 않는 fly메서드 추가, 날 수 있는 오리서브클래스에서 오버라이드 -> 오버라이드 늪
-
인터페이스를 만든다면 -> 서브 클래스에서 fly, quack 재활용하지 못함
디자인 원칙 : 애플리케이션에서 달라지는 부분을 찾아내고, 달라지지 않는 부분으로부터 분리 시킨다.
fly()와 quack()은 Duck 클래스에서 오리마다 달라지는 부분입니다.
디자인 원칙 : 구현이 아닌 인터페이스에 맞춰서 프로그래밍한다.
각 행동은 인터페이스(FlyBehavior, QuackBehavior)로 표현하고 행동을 구현할 때 이런 인터페이스를 구현한다.
-
서브클래스에서는 인터페이스로 표현되는 행동을 사용하게 됩니다. 따라서 행동을 실제로 구현한 것은 Duck 서브 클래스에 국한되지 않습니다. (FlyWithWings는 Duck에 국한되지 않습니다. Fish에도 적용할 수 있습니다.)
- 날 수도 있고, 꽥 소리지를 수도 있는 Duck 클래스를 완성하라.
public class Duck {
public FlyBehavior flyBehavior;
public QuackBehavior quackBehavior;
public void performQuack(){
quackBehavior.quack();
}
public void performFly(){
flyBehavior.fly();
}
public void swim(){
System.out.println("~수영중~");
}
public void display(){
System.out.println("오리->");
}
}
- 나머지 Duck의 서브 클래스를 완성하라.
public class MallardDuck extends Duck{
public MallardDuck() {
// TODO Auto-generated constructor stub
quackBehavior = new Quack();
flyBehavior = new FlyWithWings();
}
@Override
public void display() {
// TODO Auto-generated method stub
System.out.println("청둥오리 등 장");
}
}
-
오리는 나는 행동과 꽥 행동을 가지고 있다. 각 행동은 독립적으로 존재한다.
- 동적으로 오리의 행동을 수정할 수 있는 세터 메서드(Setter method)를 추가하라. ex) 고무 오리도 로켓을 장착하면 날 수 있다.
public abstract class Duck {
public FlyBehavior flyBehavior;
public QuackBehavior quackBehavior;
public Duck(){
}
public abstract void display();
public void performQuack(){
quackBehavior.quack();
}
public void performFly(){
flyBehavior.fly();
}
public void swim(){
System.out.println("~수영중~");
}
public void setFlyBehavior(FlyBehavior fb){
flyBehavior = fb;
}
public void setQuackBehavior(QuackBehavior qb){
quackBehavior = qb;
}
}
: Duck 클래스에서는 행동을 상속받는 대신, 올바른 행동 객체로 구성됨으로써 행동을 부여받게 됩니다.
디자인 원칙 : 상속보다는 구성을 활용한다.
구성을 이용하여 시스템을 만들면 유연성을 크게 향상시킬 수 있습니다.
-
브레인 파워(더하기 문제) : 사냥꾼들이 오리 소리(꽥꽥거리는 소리)를 내기 위해 쓰는 오리 호출기가 있다고 해 봅시다. 어떻게 하면 Duck 클래스를 상속받지 않고 오리 호출기를 구현할 수 있을까요?
-
디자인 퍼즐 : 게임 캐릭터용 클래스와 게임에서 사용할 무기의 행동에 관한 클래스가 있습니다. 각 캐릭터는 한 번에 한 가지 무기만 사용할 수 있지만 게임 도중에 무기를 바꿀 수 있습니다. 각 흩어진 클래스와 인터페이스를 조합하여 클래스 다이어그램을 그려보세요.