Headfirst设计模式的C++实现——复合模式

Posted Ren.Yu

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Headfirst设计模式的C++实现——复合模式相关的知识,希望对你有一定的参考价值。

observer.h

1 #ifndef _OBSERVER_H_
2 #define _OBSERVER_H_
3 
4 #include <string>
5 class Observer {
6 public:
7     virtual void update(const std::string &type) = 0;
8 };
9 #endif

quack_observable.h

 1 #ifndef _QUACK_OBSERVABLE_H_
 2 #define _QUACK_OBSERVABLE_H_
 3 
 4 #include "observer.h"
 5 
 6 class QuackObservable {
 7 public:
 8     virtual void register_observer(Observer *observer) = 0;
 9     virtual void notify_observers() = 0;
10 };
11 #endif

duck.h

1 #ifndef _DUCK_H_
2 #define _DUCK_H_
3 
4 #include "quack_observable.h"
5 class Duck : public QuackObservable{
6 public:
7     virtual void quack() = 0;
8 };
9 #endif

observable.h

 1 #ifndef _OBSERVABLE_H_
 2 #define _OBSERVABLE_H_
 3 
 4 #include "quack_observable.h"
 5 #include <vector>
 6 
 7 class Observable : public QuackObservable {
 8 private:
 9     std::vector<Observer *> observers;
10     const std::string type;
11 public:
12     Observable( const std::string &_type ) : type(_type) {}
13     void register_observer(Observer *observer) { observers.push_back( observer ); }
14     void notify_observers() {
15         for ( std::vector<Observer *>::iterator it = observers.begin();
16               it < observers.end();
17               it ++ ) {
18             (*it)->update( type );
19         }
20     }
21 };
22 #endif

mallard_duck.h

 1 #ifndef _MALLARD_DUCK_H_
 2 #define _MALLARD_DUCK_H_
 3 
 4 #include <iostream>
 5 #include "duck.h"
 6 #include "observable.h"
 7 
 8 class MallardDuck : public Duck{
 9 private:
10     Observable observable;
11 public:
12     MallardDuck() :observable("Mallard duck") {}
13     void quack() { std::cout << "Quack" << std::endl; notify_observers(); }
14     void register_observer(Observer *observer) { observable.register_observer(observer); }
15     void notify_observers() { observable.notify_observers(); }
16 };
17 
18 #endif

redhead_duck.h

 1 #ifndef _REDHEAD_DUCK_H_
 2 #define _REDHEAD_DUCK_H_
 3 
 4 #include <iostream>
 5 #include "duck.h"
 6 #include "observable.h"
 7 class RedheadDuck : public Duck{
 8 private:
 9     Observable observable;
10 public:
11     RedheadDuck() :observable("Redhead Duck") {}
12     void quack() { std::cout << "Quack" << std::endl; notify_observers();}
13     void register_observer(Observer *observer) { observable.register_observer(observer); }
14     void notify_observers() { observable.notify_observers(); }
15 };
16 
17 #endif

duck_call.h

 1 #ifndef _DUCK_CALL_H_
 2 #define _DUCK_CALL_H_
 3 
 4 #include <iostream>
 5 #include "duck.h"
 6 #include "observable.h"
 7 
 8 class DuckCall : public Duck{
 9 private:
10     Observable observable;
11 public:
12     DuckCall() :observable("Duck call") {}
13     void quack() { std::cout << "Kwak" << std::endl; notify_observers(); }
14     void register_observer(Observer *observer) { observable.register_observer(observer); }
15     void notify_observers() { observable.notify_observers(); }
16 };
17 
18 #endif

rubber_duck.h

 1 #ifndef _RUBBER_DUCK_H_
 2 #define _RUBBER_DUCK_H_
 3 
 4 #include <iostream>
 5 #include "duck.h"
 6 #include "observable.h"
 7 class RubberDuck : public Duck{
 8 private:
 9     Observable observable;
10 public:
11     RubberDuck() :observable("Rubber Duck") {}
12     void quack() { std::cout << "Squeak" << std::endl; notify_observers();}
13     void register_observer(Observer *observer) { observable.register_observer(observer); }
14     void notify_observers() { observable.notify_observers(); }
15 };
16 
17 #endif

countable_duck.h

 1 #ifndef _COUNTEABLE_DUCK_H_
 2 #define _COUNTEABLE_DUCK_H_
 3 
 4 #include "duck.h"
 5 class CountableDuck : public Duck{
 6 public:
 7     CountableDuck( Duck *_duck ) : duck(_duck) {}
 8     void quack() { duck->quack();  quack_count ++; }
 9     void register_observer(Observer *observer) { duck->register_observer(observer); }
10     void notify_observers() { duck->notify_observers(); }
11     static int get_quack_count() { return quack_count; }
12 private:
13     Duck *duck;
14     static int quack_count;
15 };
16 #endif

countable_duck.cpp

1 #include "countable_duck.h"
2 
3 int CountableDuck::quack_count = 0;

ivector.h

 1 #ifndef _IVECTOR_H_
 2 #define _IVECTOR_H_
 3 
 4 #include <vector>
 5 #include <stdlib.h>
 6 
 7 template<class T> class IVector {
 8 public:
 9     IVector() : pos(0) {}
10     void add( const T& t ) { t_v.push_back(t); }
11     bool has_next() { return pos < t_v.size(); }
12     T* next() {
13         if ( has_next() ) {
14             return &(t_v[pos++]);
15         }
16         return NULL;
17     }
18     void back_to_begin() { pos = 0; }
19 private:
20     int pos;
21     std::vector<T> t_v;
22 };
23 #endif

duck_factory.h

 1 #ifndef _DUCK_FACTORY_H_
 2 #define _DUCK_FACTORY_H_
 3 
 4 #include "mallard_duck.h"
 5 #include "redhead_duck.h"
 6 #include "duck_call.h"
 7 #include "rubber_duck.h"
 8 #include "countable_duck.h"
 9 #include <string>
10 
11 class SimpleDuckFactory {
12 public:
13     static Duck* create_duck( std::string type ) {
14         if ( type == "mallard" ) { return new CountableDuck( new MallardDuck ); }
15         if ( type == "redhead" ) { return new CountableDuck( new RedheadDuck ); }
16         if ( type == "call" )    { return new CountableDuck( new DuckCall ); }
17         if ( type == "rubber" )  { return new CountableDuck( new RubberDuck ); }
18         return NULL;
19     }
20 };
21 
22 class AbstractDuckFactory {
23 public:
24     static Duck *create_mallard_duck() { return new CountableDuck( new MallardDuck ); }
25     static Duck *create_redhead_duck() { return new CountableDuck( new RedheadDuck ); }
26     static Duck *create_duck_call() { return new CountableDuck( new DuckCall ); }
27     static Duck *create_rubber_duck() { return new CountableDuck( new RubberDuck ); }
28 };
29 #endif

flock.h

 1 #ifndef _FLOCK_H_
 2 #define _FLOCK_H_
 3 
 4 #include "duck.h"
 5 #include "ivector.h"
 6 
 7 class Flock : public Duck{
 8 public:
 9     void quack() {
10         ducks.back_to_begin();
11         while( ducks.has_next() ) {
12             (*(ducks.next()))->quack();
13         }
14     }
15     void add( Duck *duck ) { ducks.add(duck); }
16     void register_observer(Observer *observer) {
17         ducks.back_to_begin();
18         while( ducks.has_next() ) {
19             (*(ducks.next()))->register_observer(observer);
20         }
21     }
22     void notify_observers() {
23         ducks.back_to_begin();
24         while( ducks.has_next() ) {
25             (*(ducks.next()))->notify_observers();
26         }
27     }
28 private:
29     IVector<Duck *> ducks;
30 };
31 #endif

goose.h

1 #ifndef _GOOSE_H_
2 #define _GOOSE_H_
3 
4 #include <iostream>
5 class Goose {
6 public:
7     void honk() { std::cout << "Honk" << std::endl; }
8 };
9 #endif

goose_adapter.h

 1 #ifndef _GOOSE_ADAPTER_H_
 2 #define _GOOSE_ADAPTER_H_
 3 
 4 #include "goose.h"
 5 #include "duck.h"
 6 #include "observable.h"
 7 
 8 class GooseAdapter : public Duck{
 9 public:
10     GooseAdapter( Goose *_goose ) : goose(_goose), observable("Goose pretending to be a duck") {}
11     void quack() { goose->honk(); notify_observers();}
12     void register_observer(Observer *observer) { observable.register_observer(observer); }
13     void notify_observers() { observable.notify_observers(); }
14 private:
15     Goose *goose;
16     Observable observable;
17 };
18 #endif

quackologist.h

 1 #ifndef _QUACK_OLOGIST_H_
 2 #define _QUACK_OLOGIST_H_
 3 
 4 #include "observer.h"
 5 #include <iostream>
 6 #include <string>
 7 
 8 class QuackOlogist : public Observer {
 9 public:
10     void update(const std::string &type ) { std::cout << "Quackologist: " << type << " just quacked." << std::endl; }
11 };
12 #endif

main.cpp

 1 #include "goose_adapter.h"
 2 #include "duck_factory.h"
 3 #include "countable_duck.h"
 4 #include <iostream>
 5 #include "flock.h"
 6 #include "quackologist.h"
 7 
 8 void simulate(Duck *duck) {
 9     if ( NULL != duck ) { duck->quack(); }
10 }
11 
12 int main() {
13     Flock *flock_of_mallard = new Flock;
14     flock_of_mallard->add( AbstractDuckFactory::create_mallard_duck() );
15     flock_of_mallard->add( AbstractDuckFactory::create_mallard_duck() );
16  
17     Flock *flock_of_ducks = new Flock;
18 
19     flock_of_ducks->add( new CountableDuck(new GooseAdapter( new Goose )));
20 
21     flock_of_ducks->add( AbstractDuckFactory::create_redhead_duck() );
22     flock_of_ducks->add( AbstractDuckFactory::create_duck_call() );
23     flock_of_ducks->add( AbstractDuckFactory::create_rubber_duck() );
24    
25     flock_of_ducks->add( flock_of_mallard );
26 
27     QuackOlogist quackologist;
28     flock_of_ducks->register_observer(&quackologist);
29 
30     simulate( flock_of_ducks );
31 
32     std::cout << "quack count: " << CountableDuck::get_quack_count() << std::endl;
33 };

 

以上是关于Headfirst设计模式的C++实现——复合模式的主要内容,如果未能解决你的问题,请参考以下文章

Headfirst设计模式的C++实现——简单工厂模式(Simple Factory)之二

Headfirst设计模式的C++实现——抽象工厂(Abstract Factory)

Headfirst设计模式的C++实现——迭代器(Iterator)

Headfirst设计模式的C++实现——迭代器(Iterator)改良版

装饰者模式C++实现

工厂模式C++实现