鸭子例子的综合应用。背景参见原书。以下为c++实现。
#include <iostream>
#include <vector>
using namespace std;
class Observer; //解决类的循环依赖
class QuackObservable
{
public:
virtual void registerObserver(Observer* observer){ }
virtual void notifyObservers(){ }
virtual void print(){ }
};
class Observer
{
public:
virtual void update(QuackObservable* duck){ }
};
class Quackable : public QuackObservable
{
public:
virtual void quack(){ }
};
class Observable : public QuackObservable
{
public:
vector<Observer*>* observers;
QuackObservable* duck;
Observable(QuackObservable* duck)
{
observers = new vector<Observer*>();
this->duck = duck;
}
virtual void registerObserver(Observer* observer)
{
observers->push_back(observer);
}
virtual void notifyObservers()
{
vector<Observer*>::iterator iter = observers->begin();
while(iter != observers->end())
{
(*iter)->update(duck);
++iter;
}
}
};
class MallardDuck : public Quackable
{
public:
Observable* observable;
MallardDuck()
{
observable = new Observable(this);
}
virtual void registerObserver(Observer* observer)
{
observable->registerObserver(observer);
}
void notifyObservers()
{
observable->notifyObservers();
}
virtual void quack()
{
cout << "Quack" << endl;
notifyObservers();
}
virtual void print()
{
cout << "Mallard duck";
}
};
class RedheadDuck : public Quackable
{
public:
Observable* observable;
RedheadDuck()
{
observable = new Observable(this);
}
virtual void notifyObservers()
{
observable->notifyObservers();
}
virtual void registerObserver(Observer* observer)
{
observable->registerObserver(observer);
}
virtual void quack()
{
cout << "Quack" << endl;
notifyObservers();
}
virtual void print()
{
cout << "Redhead duck";
}
};
class DuckCall : public Quackable
{
public:
Observable* observable;
DuckCall()
{
observable = new Observable(this);
}
virtual void notifyObservers()
{
observable->notifyObservers();
}
virtual void registerObserver(Observer* observer)
{
observable->registerObserver(observer);
}
virtual void quack()
{
cout << "Kwak" << endl;
notifyObservers();
}
virtual void print()
{
cout << "Ducall";
}
};
class RubberDuck : public Quackable
{
public:
Observable* observable;
RubberDuck()
{
observable = new Observable(this);
}
virtual void notifyObservers()
{
observable->notifyObservers();
}
virtual void registerObserver(Observer* observer)
{
observable->registerObserver(observer);
}
virtual void quack()
{
cout << "Squeak" << endl;
notifyObservers();
}
virtual void print()
{
cout << "rubber duck" ;
}
};
class Goose
{
public:
virtual void honk()
{
cout <<"Honk" <<endl;
}
virtual void print()
{
cout << "Goose" ;
}
};
class GooseAdapter : public Quackable
{
public:
Goose* goose;
Observable* observable;
GooseAdapter(Goose* goose)
{
this->goose = goose;
observable = new Observable(this);
}
virtual void notifyObservers()
{
observable->notifyObservers();
}
virtual void registerObserver(Observer* observer)
{
observable->registerObserver(observer);
}
void quack()
{
goose->honk();
notifyObservers();
}
virtual void print()
{
cout << "Goose pretending to be a Duck";
}
};
class QuackCounter : public Quackable
{
public:
Quackable* duck;
static int numberOfQuacks;
QuackCounter(Quackable* duck)
{
this->duck = duck;
}
void quack()
{
duck->quack();
numberOfQuacks++;
}
static int getQuacks()
{
return numberOfQuacks;
}
virtual void registerObserver(Observer* observer)
{
duck->registerObserver(observer);
}
virtual void notifyObservers()
{
duck->notifyObservers();
}
virtual void print()
{
duck->print();
}
};
int QuackCounter::numberOfQuacks = 0;//一定要在类之外初始化静态变量
class AbstractDuctFactory
{
public:
virtual Quackable* createMallardDuck()
{
return new QuackCounter(new MallardDuck());
}
virtual Quackable* createRedheadDuck()
{
return new QuackCounter(new RedheadDuck());
}
virtual Quackable* createDuckCall()
{
return new QuackCounter(new DuckCall());
}
virtual Quackable* createRubberDuck()
{
return new QuackCounter(new RubberDuck());
}
};
class DuckFactory : public AbstractDuctFactory
{
public:
virtual Quackable* createMallardDuck()
{
return new MallardDuck();
}
virtual Quackable* createRedheadDuck()
{
return new RedheadDuck();
}
virtual Quackable* createDuckCall()
{
return new DuckCall();
}
virtual Quackable* createRubberDuck()
{
return new RubberDuck();
}
};
class CoutingDuckFactory : public AbstractDuctFactory
{
public:
virtual Quackable* createMallardDuck()
{
return new QuackCounter(new MallardDuck());
}
virtual Quackable* createRedheadDuck()
{
return new QuackCounter(new RedheadDuck());
}
virtual Quackable* createDuckCall()
{
return new QuackCounter(new DuckCall());
}
virtual Quackable* createRubberDuck()
{
return new QuackCounter(new RubberDuck());
}
};
class Flock : public Quackable
{
public:
vector<Quackable*>* ducks;
Flock()
{
ducks = new vector<Quackable*>();
}
void add(Quackable* duck)
{
ducks->push_back(duck);
}
virtual void quack()
{
vector<Quackable*>::iterator iter = ducks->begin();
while(iter != ducks->end())
{
(*iter)->quack();
++iter;
}
}
virtual void registerObserver(Observer* observer)
{
vector<Quackable*>::iterator iter = ducks->begin();
while(iter != ducks->end())
{
(*iter)->registerObserver(observer);
++iter;
}
}
virtual void print()
{
cout << "Flocks of Ducks";
}
};
class Quackologist : public Observer
{
public:
virtual void update(QuackObservable* duck)
{
cout << "Quackologist: ";
duck->print() ;
cout <<" just quacked." << endl;;
}
};
void simulate(Quackable* duck)
{
duck->quack();
}
void simulate(AbstractDuctFactory* duckFactory)
{
Quackable* mallardDuck =duckFactory->createMallardDuck();
Quackable* redheadDuck = duckFactory->createRedheadDuck();
Quackable* duckCall = duckFactory->createDuckCall();
Quackable* rubberDuck = duckFactory->createRubberDuck();
Quackable* gooseDuck = new GooseAdapter(new Goose());
cout << "\nDuck Simulator: With composite - Flocks" << endl;
Flock* flockOfDucks = new Flock();
flockOfDucks->add(redheadDuck);
flockOfDucks->add(duckCall);
flockOfDucks->add(rubberDuck);
flockOfDucks->add(gooseDuck);
Flock* flockOfMallards = new Flock();
Quackable* mallardOne = duckFactory->createMallardDuck();
Quackable* mallardTwo = duckFactory->createMallardDuck();
Quackable* mallardThree = duckFactory->createMallardDuck();
Quackable* mallardFour = duckFactory->createMallardDuck();
flockOfMallards->add(mallardOne);
flockOfMallards->add(mallardTwo);
flockOfMallards->add(mallardThree);
flockOfMallards->add(mallardFour);
flockOfDucks->add(flockOfMallards);
cout << endl << "\nDuck Simulator: with Observer" << endl;
Quackologist* quackologist = new Quackologist();
flockOfDucks->registerObserver(quackologist);
simulate(flockOfDucks);
cout << "The ducks quacked " << QuackCounter::getQuacks() <<" times" <<endl;
}
int main()
{
AbstractDuctFactory* duckFactory = new CoutingDuckFactory();
simulate(duckFactory);
return 0;
}