FirstHead 디자인 패턴에 나온 첫번째 디자인패턴입죠.
자바로 나와 있는 것을 C++로 변형해 보았습니다.
오늘 자바책으 살짝 보니 첫장에 '자바는 C++에서 어렵다는 포인터를 사용하지 않는다!' 라는 글을 보고 살짝 화들짝.
...그건 그렇다고 하고.
객체가 잘 짜여 있는지 한 번 슥슥 보면서 생각이라도 해 주시면 감사하겠습니다.
역시 코딩은 즐겁단 말이죠=_=;
-------------------------------------------------------------------------------------------------------
#include <iostream>
#include <Turboc.h>
using namespace std;
/////////////////////////////////////////////////////////////////////////
class FlyBehavior {
public:
virtual void Fly()=0;
};
class FlyWithWings : public FlyBehavior {
public:
virtual void Fly() { cout << "날개와 함께 날아가냐" << endl; }
};
class FlyNoWay : public FlyBehavior {
public:
virtual void Fly() { cout << "날개 없어서 못날아엽" << endl; }
};
////////////////////////////////////////////////////////////////////////
class QuackBehavior {
public:
virtual void quack()=0;
};
class Quack : public QuackBehavior {
public:
virtual void quack() { cout << "꽥꽥꽥 " << endl; }
};
class Squack : public QuackBehavior {
public:
virtual void quack() { cout << "스꽥 스꽥" << endl; }
};
class MuteQuack : public QuackBehavior {
public:
virtual void quack() { cout << "... ..." << endl; }
};
///////////////////////////////////////////////////////////////////////////
class Duck {
protected:
FlyBehavior *flyBehavior;
QuackBehavior *quackBehavior;
public:
void swim();
void display() {quackBehavior->quack(); flyBehavior->Fly(); }
void performQuack() { quackBehavior->quack(); }
void performFly() { flyBehavior->Fly(); }
void SetperformQuack (QuackBehavior *qb) {quackBehavior = qb; }
void SetperformFly (FlyBehavior *fb) {flyBehavior = fb; }
};
class RubberDuck : public Duck {
public:
RubberDuck() { flyBehavior = new FlyNoWay(); quackBehavior = new MuteQuack(); }
~RubberDuck() { delete flyBehavior; delete quackBehavior;}
};
class RedheadDuck : public Duck {
public:
RedheadDuck() { flyBehavior = new FlyNoWay(); quackBehavior = new Quack(); }
~RedheadDuck() { delete flyBehavior; delete quackBehavior; }
};
////////////////////////////////////////////////////////////////////////////
void main()
{
Duck *Rubber = new RubberDuck();
Rubber->display();
Rubber->SetperformFly(new FlyWithWings() );
Rubber->display();
delete Rubber;
}
------------------------------------------------------------------------------
FlyBehavior/QuackBehavior의 소멸자를 가상함수로 하시고 Duck의 소멸자에서 일괄적으로 해제,
performFly/performQuack시의 포인터 유효성 검사,
그리고 기왕 위 함수들을 만드셨으니 display에서는 유효성 검사를 수반하는 위 함수들을 호출,
RubberDuck/RedheadDuck의 생성자에서 대입문을 이용하기보다는 초기화 목록을 이용,
마지막으로 Duck의 소멸자를 가상함수로 - 위의 경우는 RubberDuck과 RedheadDuck에 데이터 멤버가 없으니 상관 없지만, 데이터 멤버가 있을 경우 상위 클래스의 소멸자가 가상함수가 아니라면 소멸시 메모리 릭이 생깁니다.