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 };
时间: 06-18

Headfirst设计模式的C++实现——复合模式的相关文章

Headfirst设计模式的C++实现——策略模式(Strategy)

前言 最近在学习<Headfirst设计模式>,里面的例子都是Java的.但是我对Java并不熟悉,所以试着用C++来实现书中的例子. 先来看看Duck以及子类 Duck.h 1 #include <iostream> 2 #include "FlyBehavior.h" 3 4 class Duck 5 { 6 private: 7 FlyBehavior *m_p_fly_behavior; 8 public: 9 virtual void quack()

Headfirst设计模式的C++实现——组合模式(Composite)

menu_component.h 1 #ifndef _MENU_COMPONENT_H_ 2 #define _MENU_COMPONENT_H_ 3 4 #include <string> 5 6 class MenuComponent { 7 public: 8 class Iterator { 9 public: 10 virtual bool has_next() = 0; 11 12 virtual MenuComponent *next() = 0; 13 }; 14 15 Me

复合模式Compound -- 学习HeadFirst设计模式记录

? 复合模式:结合两个或以上的模式,组成一个解决方案,解决一再发生的一般性问题. ? 典型应用:MVC模式,M:Model, V:View, C:Controller.类似的还有Web:浏览器/服务器模型. ? ?

Java 设计模式 -- 复合模式之一

关于复合模式: 在形式上,复合模式确实是多个模式的组合,但满足了这一条并不一定是复合模式,注意它的定义:将多个模式结合起来形成一个"框架",以解决一般性问题             一提到"框架",可能最容易联想到的就是MVC吧,不过MVC确实是一个经典的复合模式 在进去MVC模式之前 先看一个简单的例子: 例子来自Headfrist 设计模式中的经典鸭鸣:有四种鸭鸣, 绿头鸭,叫声 Quack 红头鸭,叫声 Quack 鸭鸣器,叫声 Kwak 橡皮鸭,叫声 Squ

Java 设计模式 -- 复合模式之二

接着上文的鸭鸣例子:Java 设计模式 -- 复合模式之一 上文中,我们的鸭鸣实现了 装饰者模式  适配器模式  工厂模式的结合 现在,又需要进行改动了,上文,是可以统计一群鸭子的叫声,现在需要能够观察个别鸭子的行为 引入观察者模式: 任何想被观察的Quackable都必须实现下面的接口 public interface QuackObservable { public void registerObserver(Observer observer); public void notifyobs

HeadFirst 设计模式 04 工厂模式

除了 new 操作符之外, 还有更多创造对象的方法. 工厂处理创建对象的细节. 这么做的目的是为了抽象, 例如把创建比萨的代码包装进一个类, 当以后实现改变时, 只需修改这个类即可. 利用静态方法定义一个简单的工厂, 这是很常见的技巧, 被称作静态工厂. 所有工厂模式斗都用来封装对象的创建, javascript 也是一样. 工厂方法模式通过让子类决定该创建的对象是什么, 来达到将对象创建的过程封装的目的. 工厂模式定义了一个创建对象的接口, 但由子类决定要实例化的类是哪一个. 工厂方法让类把实

MVC模式 - 一种复合模式

MVC模式可以说是我们从事WEB开发人员最常见的模式 实际上,它是复合模式,一种由2个及以上的设计模式组成的设计模式 实际上是三个组件组成的模式,数据模型.视图.控制器 可以看得出来,实际上MVC是由观察者.组合.策略模式所组成的复合模式

Php设计模式(三):行为型模式part2

原文详见:http://www.ucai.cn/blogdetail/7023?mid=1&f=5 可以在线运行查看效果哦! <接上文> 5.中介者模式(Mediator) : 用中介对象封装一系列的对象交互,中介使各对象不需要显式地相互引用.类似于邮局,邮寄者和收件者不用自己跑很远路,通过邮局就可以. 好处:简化了对象之间的关系,减少子类的生成. 弊端:中介对象可能变得非常复杂,系统难以维护. 应用场景:不需要显示地建立交互. 代码实现: ? 1 2 3 4 5 6 7 8 9 10

并行设计模式(二)-- Master-Worker模式

Java多线程编程中,常用的多线程设计模式包括:Future模式.Master-Worker模式.Guarded Suspeionsion模式.不变模式和生产者-消费者模式等.这篇文章主要讲述Master-Worker模式,关于其他多线程设计模式的地址如下: 关于Future模式的详解:并行设计模式(一)-- Future模式 关于Guarded Suspeionsion模式的详解:并行设计模式(三)-- Guarded Suspeionsion模式 关于不变模式的详解:并行设计模式(四)--