기본적인 구조는 최상위 클래스를 상속받아 그 클래스들에 기능을 추가한다. 라고 보는게 맞을듯.
어떤 상황에 좋은가?
서로 행위만 다를 뿐 밀접한 연관 관계를 가지는 여러 클래스들에 대해 필요한 시점에 어느 한 행위를 수행하는 클래스를 골라 사용하고자 할 때 유용하다.
저장 공간 사용 효율이나 실행 시간 효율 등의 측면에서 다양한 형태의 알고리즘(기능)이 존재해서 상황에 따라 최적의 알고리즘(기능)을 선택해서 사용하도록 할 때 유용하다.
어떤 알고리즘(기능)이 Client가 알아서는 안될 데이터를 사용하거나 알고리즘(기능)에 종속된 복잡한 자료구조(속성)를 사용할 때 유용하다. 이 경우 Strategy 패턴은 Client에게 알고리즘(기능)이 사용하는 데이터나 자료구조(속성)를 숨겨주는 역활을 한다.
어떤 클래스가 많은 행위를 가지고 있고 이것이 여러 개의 조건문 형태로 쭉 나열되는 형태일 때 많은 조건문 대신 Strategy 패턴을 사용하면 유용하다. 이때 각 조건에 따라 수행할 때용들은 Strategey의 하위 클래스로 정의 될 것이다.
예제의 기능은, 최상위 오리 클래스를 상속 받아,
다양한 오리들을 생성하고, 사용한다.
Duck.h
#ifndef __DUCK_H__
#define __DUCK_H__
#include "FlyBehavior.h"
#include "QuackBehavior.h"
/* 오리 클래스 */
class Duck
{
FlyBehavior* flyBehavior;
QuackBehavior* quackBehavior;
public:
~Duck();
void swim();
virtual void display() = 0;
void performFly();
void performQuack();
void SetFlyBehavior(FlyBehavior* f);
void SetQuackBehacior(QuackBehavior* q);
};
#endif
Duck.Cpp
#include <iostream>
#include "Duck.h"
void Duck::swim()
{
std::cout << "수영중" << std::endl;
}
void Duck::performFly()
{
flyBehavior->fly();
}
void Duck::performQuack()
{
quackBehavior->quack();
}
void Duck::SetFlyBehavior(FlyBehavior* f)
{
flyBehavior = f;
}
void Duck::SetQuackBehacior(QuackBehavior* q)
{
quackBehavior = q;
}
Duck::~Duck()
{
delete flyBehavior;
delete quackBehavior;
}
FlyBehavior.h
#ifndef __FLYBEHAVIOR_H__
#define __FLYBEHAVIOR_H__
// 하늘을 나는 기능
/* FlayBehavior Class */
class FlyBehavior
{
public:
virtual void fly() = 0;
};
/* FlyWithWings : public FlyBehavior */
class FlyWithWings : public FlyBehavior
{
public:
void fly();
};
/* FlyNoWay : public FlyBehavior */
class FlyNoWay : public FlyBehavior
{
public:
void fly();
};
class FlyRoket : public FlyBehavior
{
public:
void fly();
};
#endif
FlyBehavior.cpp
#include <iostream>
#include "FlyBehavior.h"
void FlyWithWings::fly()
{
std::cout << "오리가 난다." << std::endl;
}
void FlyNoWay::fly()
{
std::cout << "오리가 못 난다." << std::endl;
}
void FlyRoket::fly()
{
std::cout << "오리가 로켓으로 난다." << std::endl;
}
QuackBehavior.h
QuackBehavior.h
#include <iostream>
#include "QuackBehavior.h"
void Quack::quack()
{
std::cout << "오리가 꽥꽥" << std::endl;
}
void Squack::quack()
{
std::cout << "오리가 삑삑" << std::endl;
}
void MuteQuack::quack()
{
std::cout << "오리가 조용" << std::endl;
}
void CallQuack::quack()
{
std::cout << "사냥꾼이 호출버튼을 눌러 오리 소리를 냅니다." << std::endl;
}
main.cpp
#include <iostream>
#include "FlyBehavior.h"
#include "Duck.h"
#include "QuackBehavior.h"
class DecoyDuck : public Duck
{
public:
void display()
{
std::cout << "가짜 오리 출력 " << std::endl;
}
};
class MallardDuck : public Duck
{
public:
void display()
{
std::cout << "청둥 오리 출력" << std::endl;
}
};
class RedheadDuck : public Duck
{
public:
void display()
{
std::cout << "빨간 머리 오리 출력" << std::endl;
}
};
void main()
{
// 가짜 오리
DecoyDuck decoyduck;
// 청둥 오리
MallardDuck mallarduck;
// 빨간 머리 오리
RedheadDuck redheadduck;
// 호출기 생성
CallQuack callquack;
// 가짜 오리의 능력들 삽입
decoyduck.SetFlyBehavior(new FlyRoket);
decoyduck.SetQuackBehacior(new Squack);
// 청둥 오리의 능력들 삽입
mallarduck.SetFlyBehavior(new FlyWithWings);
mallarduck.SetQuackBehacior(new Quack);
// 빨간 머리 오리의 능력들 삽입
redheadduck.SetFlyBehavior(new FlyWithWings);
redheadduck.SetQuackBehacior(new Quack);
// 가짜 오리 사용
decoyduck.display();
decoyduck.performQuack();
decoyduck.performFly();
decoyduck.swim();
std::cout << std::endl;
// 청둥 오리 사용
mallarduck.display();
mallarduck.performQuack();
mallarduck.performFly();
std::cout << std::endl;
// 빨간 머리 오리 사용
redheadduck.display();
redheadduck.performQuack();
redheadduck.performFly();
redheadduck.swim();
std::cout << std::endl;
// 호출기 사용
callquack.quack();
}
'프로그래밍 > 디자인패턴' 카테고리의 다른 글
Iterator Pattern (0) | 2016.05.04 |
---|---|
UML의 기본 구성-시퀀스 다이어그램 (4) | 2016.05.02 |
UML의 기본 구성-클래스 다이어그램 (0) | 2016.05.02 |
다시 시작하는 디자인패턴 (0) | 2016.04.29 |
데코레이터(Decorator) 패턴 (1) | 2010.04.04 |