您的位置:首页 > 编程语言 > C语言/C++

20/23种设计模式---C++实现

2011-08-10 14:17 447 查看
笨博文直接拷贝PDF文档所得,部分图片不能显示:

常见设计模式的解析和实现
常见设计模式的解析和实现(C++)之一-Factory模式
作用:
定义一个用于创建对象的接口,让子类决定实例化哪一个类。Factory Method
使一个类的实例化延迟到其子类。
UML结构图:
抽象基类:
1)Product:创建出来的对象的抽象基类.
2)Factory创建对象的工厂方法的抽象基类.
接口函数:
1)Creator::FactoryMethod:纯虚函数,由派生类实现,创建出对应的Product.
解析:
在这个模式中,有两个抽象基类,一个是Product为创建出来的对象的抽象基类,
一个是Factory是工厂的抽象基类,在互相协作的时候都是由相应的Factory派
生类来生成Product的派生类,也就是说如果要新增一种Product那么也要对应
的新增一个Factory,创建的过程委托给了这个Factory.也就是说一个Factory
和一个Product是一一对应的关系.
备注:
设计模式的演示图上把Factory类命名为Creator,下面的实现沿用了这个命名.
演示实现:
1)Factory.h
PDF created with pdfFactory trial version www.pdffactory.com
/**************************************************************
******
created: 2006/06/30
filename: Factory.h
author: 李创
http://www.cppblog.com/converse/
purpose: Factory模式的演示代码
****************************************************************
*****/
#ifndef FACTORY_H
#define FACTORY_H
class Product
{
public:
Product(){}
virtual ~Product(){}
};
class ConcreateProduct
: public Product
{
public:
ConcreateProduct();
virtual ~ConcreateProduct();
};
class Creator
{
public:
Creator(){}
virtual ~Creator(){}
void AnOperation();
protected:
virtual Product* FactoryMethod() = 0;
};
class ConcreateCreator
: public Creator
{
PDF created with pdfFactory trial version www.pdffactory.com
public:
ConcreateCreator();
virtual ~ConcreateCreator();
protected:
virtual Product* FactoryMethod();
};
#endif
2)Factory.cpp
/**************************************************************
******
created: 2006/06/30
filename: Factory.cpp
author: 李创
http://www.cppblog.com/converse/
purpose: Factory模式的演示代码
****************************************************************
*****/
#include "Factory.h"
#include <iostream>
using namespace std;
ConcreateProduct::ConcreateProduct()
{
std::cout << "construction of ConcreateProduct\n";
}
ConcreateProduct::~ConcreateProduct()
{
std::cout << "destruction of ConcreateProduct\n";
}
void Creator::AnOperation()
{
Product* p = FactoryMethod();
std::cout << "an operation of product\n";
}
PDF created with pdfFactory trial version www.pdffactory.com
ConcreateCreator::ConcreateCreator()
{
std::cout << "construction of ConcreateCreator\n";
}
ConcreateCreator::~ConcreateCreator()
{
std::cout << "destruction of ConcreateCreator\n";
}
Product* ConcreateCreator::FactoryMethod()
{
return new ConcreateProduct();
}
3)Main.cpp(测试代码)
/**************************************************************
******
created: 2006/06/30
filename: Main.cpp
author: 李创
http://www.cppblog.com/converse/
purpose: 测试Factory模式的代码
****************************************************************
*****/
#include "Factory.h"
#include <stdlib.h>
int main(int argc,char* argv[])
{
Creator *p = new ConcreateCreator();
p->AnOperation();
delete p;
system("pause");
return 0;
}
PDF created with pdfFactory trial version www.pdffactory.com
常见设计模式的解析和实现(C++)之二-Abstract Fa
ctory模式
作用:
提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。
UML结构图:
抽象基类:
1)ProductA,ProductB:分别代表不同类型的产品,而它们的派生类则是这种产
品的一个实现.
2)AbstractFactory:生产这一系列产品的一个抽象工厂,它的派生类是不同的
实现.
接口函数:
1)AbstractFactory::CreateProductA和AbstractFactory::CreateProduc
tB:分别是生产不同产品的不同的实现,由各个派生出来的抽象工厂实现之.
解析:
Abstract Factory模式和Factory最大的差别就是抽象工厂创建的是一系列相
关的对象,其中创建的实现其实采用的就是Factory模式的方法,对于某个实现
的有一个派生出来的抽象工厂,另一个实现有另一个派生出来的工厂,等等.
PDF created with pdfFactory trial version www.pdffactory.com
可以举一个简单的例子来解释这个模式:比如,同样是鸡腿(ProductA)和汉堡(P
roductB),它们都可以有商店出售(AbstractFactory),但是有不同的实现,有肯
德基(ConcreateFactory1)和麦当劳(ConcreateFactory2)两家生产出来的
不同风味的鸡腿和汉堡(也就是ProductA 和ProductB的不同实现).
而负责生产汉堡和鸡腿的就是之前提过的Factory模式了.
抽象工厂需要特别注意的地方就是区分不同类型的产品和这些产品的不同实现.
显而易见的,如果有n种产品同时有m中不同的实现,那么根据乘法原理可知有n
*m个Factory模式的使用.
实现:
1)AbstractFactory.h
/**************************************************************
******
created: 2006/07/19
filename: AbstractFactory.h
author: 李创
http://www.cppblog.com/converse/
purpose: AbstractFactory的演示代码
****************************************************************
*****/
#ifndef ABSTRACTFACTORY_H
#define ABSTRACTFACTORY_H
// 抽象基类AbstractProductA,代表产品A的抽象
class AbstractProductA
{
public:
AbstractProductA() {}
virtual ~AbstractProductA(){};
};
// 派生类ConcreateProductA1,继承自AbstractProductA,代表产品A的第一种实现
class ConcreateProductA1
: public AbstractProductA
{
public:
ConcreateProductA1();
virtual ~ConcreateProductA1();
};
PDF created with pdfFactory trial version www.pdffactory.com
// 派生类ConcreateProductA2,继承自AbstractProductA,代表产品A的第二种实现
class ConcreateProductA2
: public AbstractProductA
{
public:
ConcreateProductA2();
virtual ~ConcreateProductA2();
};
// 抽象基类AbstractProductB,代表产品B的抽象
class AbstractProductB
{
public:
AbstractProductB() {}
virtual ~AbstractProductB(){};
};
// 派生类ConcreateProductB1,继承自AbstractProductB,代表产品B的第一种实现
class ConcreateProductB1
: public AbstractProductB
{
public:
ConcreateProductB1();
virtual ~ConcreateProductB1();
};
// 派生类ConcreateProductB2,继承自AbstractProductB,代表产品B的第二种实现
class ConcreateProductB2
: public AbstractProductB
{
public:
ConcreateProductB2();
virtual ~ConcreateProductB2();
};
// 抽象基类AbstractFactory,工厂的抽象类,生产产品A和产品B
class AbstractFactory
{
public:
AbstractFactory(){}
virtual ~AbstractFactory(){}
virtual AbstractProductA* CreateProductA() = 0;
virtual AbstractProductB* CreateProductB() = 0;
PDF created with pdfFactory trial version www.pdffactory.com
};
// 派生类ConcreateFactory1,继承自AbstractFactory
// 生产产品A和产品B的第一种实现
class ConcreateFactory1
: public AbstractFactory
{
public:
ConcreateFactory1();
virtual ~ConcreateFactory1();
virtual AbstractProductA* CreateProductA();
virtual AbstractProductB* CreateProductB();
};
// 派生类ConcreateFactory2,继承自AbstractFactory
// 生产产品A和产品B的第二种实现
class ConcreateFactory2
: public AbstractFactory
{
public:
ConcreateFactory2();
virtual ~ConcreateFactory2();
virtual AbstractProductA* CreateProductA();
virtual AbstractProductB* CreateProductB();
};
#endif
2)AbstractFactory.cpp
/**************************************************************
******
created: 2006/07/19
filename: AbstractFactory.cpp
author: 李创
http://www.cppblog.com/converse/
purpose: AbstractFactory的演示代码
****************************************************************
*****/
#include <iostream>
#include "AbstractFactory.h"
PDF created with pdfFactory trial version www.pdffactory.com
ConcreateProductA1::ConcreateProductA1()
{
std::cout << "construction of ConcreateProductA1\n";
}
ConcreateProductA1::~ConcreateProductA1()
{
std::cout << "destruction of ConcreateProductA1\n";
}
ConcreateProductA2::ConcreateProductA2()
{
std::cout << "construction of ConcreateProductA2\n";
}
ConcreateProductA2::~ConcreateProductA2()
{
std::cout << "destruction of ConcreateProductA2\n";
}
ConcreateProductB1::ConcreateProductB1()
{
std::cout << "construction of ConcreateProductB1\n";
}
ConcreateProductB1::~ConcreateProductB1()
{
std::cout << "destruction of ConcreateProductB1\n";
}
ConcreateProductB2::ConcreateProductB2()
{
std::cout << "construction of ConcreateProductB2\n";
}
ConcreateProductB2::~ConcreateProductB2()
{
std::cout << "destruction of ConcreateProductB2\n";
}
ConcreateFactory1::ConcreateFactory1()
{
std::cout << "construction of ConcreateFactory1\n";
PDF created with pdfFactory trial version www.pdffactory.com
}
ConcreateFactory1::~ConcreateFactory1()
{
std::cout << "destruction of ConcreateFactory1\n";
}
AbstractProductA* ConcreateFactory1::CreateProductA()
{
return new ConcreateProductA1();
}
AbstractProductB* ConcreateFactory1::CreateProductB()
{
return new ConcreateProductB1();
}
ConcreateFactory2::ConcreateFactory2()
{
std::cout << "construction of ConcreateFactory2\n";
}
ConcreateFactory2::~ConcreateFactory2()
{
std::cout << "destruction of ConcreateFactory2\n";
}
AbstractProductA* ConcreateFactory2::CreateProductA()
{
return new ConcreateProductA2();
}
AbstractProductB* ConcreateFactory2::CreateProductB()
{
return new ConcreateProductB2();
}
3)Main.cpp(测试代码)
/**************************************************************
******
created: 2006/07/19
filename: Main.cpp
author: 李创
http://www.cppblog.com/converse/
PDF created with pdfFactory trial version www.pdffactory.com
purpose: AbstractFactory的测试代码
****************************************************************
*****/
#include "AbstractFactory.h"
#include <stdlib.h>
int main()
{
// 生产产品A的第一种实现
ConcreateFactory1 *pFactory1 = new ConcreateFactory1;
AbstractProductA *pProductA = pFactory1->CreateProductA();
// 生产产品B的第二种实现
ConcreateFactory2 *pFactory2 = new ConcreateFactory2;
AbstractProductB *pProductB = pFactory2->CreateProductB();
delete pFactory1;
delete pProductA;
delete pFactory2;
delete pProductB;
system("pause");
return 0;
}
常见设计模式的解析和实现(C++)之三-Builder模式
作用:
将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表
示。
UML结构图:
PDF created with pdfFactory trial version www.pdffactory.com
适用于以下情况:
1)当创建复杂对象的算法应该独立于该对象的组成部分以及它们的装配方式时。
2)当构造过程必须允许被构造的对象有不同的表示时。
抽象基类:
1)Builder:这个基类是全部创建对象过程的抽象,提供构建不同组成部分的接口
函数
接口:
1)Builder::BuildPartA,Builder::BuildPartB:是对一个对象不同部分的构建
函数接口,Builder的派生类来具体实现.
另外还有一个需要注意的函数,就是Director::Construct函数,这个函数里面
通过调用上面的两个接口函数完成对象的构建--也就是说各个不同部分装配的
过程都是一致的(同样的调用的Construct函数),但是不同的构建方式会有不同
的表示(根据Builder的实际类型来决定如何构建,也就是多态)
解析:
Builder模式是基于这样的一个情况:一个对象可能有不同的组成部分,这几个部
分的不同的创建对象会有不同的表示,但是各个部分之间装配的方式是一致的.
比方说一辆单车,都是由车轮车座等等的构成的(一个对象不同的组成部分),不
同的品牌生产出来的也不一样(不同的构建方式).虽然不同的品牌构建出来的单
车不同,但是构建的过程还是一样的(哦,你见过车轮长在车座上的么?).
也就是说,Director::Construct函数中固定了各个组成部分的装配方式,而具体
是装配怎样的组成部分由Builder的派生类实现.
实现:
Builder模式的实现基于以下几个面向对象的设计原则:1)把变化的部分提取出
来形成一个基类和对应的接口函数,在这里不会变化的是都会创建PartA 和Par
tB,变化的则是不同的创建方法,于是就抽取出这里的Builder基类和BuildPart
A,BuildPartB接口函数2)采用聚合的方式聚合了会发生变化的基类,就是这里
PDF created with pdfFactory trial version www.pdffactory.com
Director聚合了Builder类的指针.
1)Builder.h
/* ***********************************************************
********
created: 2006/07/19
filename: Builder.h
author: 李创
http://www.cppblog.com/converse/
purpose: Builder模式的演示代码
****************************************************************
**** */
#ifndef BUILDER_H
#define BUILDER_H
// 虚拟基类,是所有Builder的基类,提供不同部分的构建接口函数
class Builder
{
public :
Builder() {} ;
virtual ~ Builder() {}
// 纯虚函数,提供构建不同部分的构建接口函数
virtual void BuilderPartA() = 0 ;
virtual void BuilderPartB() = 0 ;
} ;
// 使用Builder构建产品,构建产品的过程都一致,但是不同的builder有不同的实现
// 这个不同的实现通过不同的Builder派生类来实现,存有一个Builder的指针,通过这个来
实现多态调用
class Director
{
public :
Director(Builder * pBuilder);
~ Director();
void Construct();
private :
Builder * m_pBuilder;
} ;
PDF created with pdfFactory trial version www.pdffactory.com
// Builder的派生类,实现BuilderPartA和BuilderPartB接口函数
class ConcreateBuilder1
: public Builder
{
public :
ConcreateBuilder1() {}
virtual ~ ConcreateBuilder1() {}
virtual void BuilderPartA();
virtual void BuilderPartB();
} ;
// Builder的派生类,实现BuilderPartA和BuilderPartB接口函数
class ConcreateBuilder2
: public Builder
{
public :
ConcreateBuilder2() {}
virtual ~ ConcreateBuilder2() {}
virtual void BuilderPartA();
virtual void BuilderPartB();
} ;
#endif
2)Builder.cpp
/* ***********************************************************
********
created: 2006/07/19
filename: Builder.cpp
author: 李创
http://www.cppblog.com/converse/
purpose: Builder模式的演示代码
****************************************************************
**** */
#include " Builder.h "
#include < iostream >
void ConcreateBuilder1::BuilderPartA()
PDF created with pdfFactory trial version www.pdffactory.com
{
std::cout << " BuilderPartA by ConcreateBuilder1\n " ;
}
void ConcreateBuilder1::BuilderPartB()
{
std::cout << " BuilderPartB by ConcreateBuilder1\n " ;
}
void ConcreateBuilder2::BuilderPartA()
{
std::cout << " BuilderPartA by ConcreateBuilder2\n " ;
}
void ConcreateBuilder2::BuilderPartB()
{
std::cout << " BuilderPartB by ConcreateBuilder2\n " ;
}
Director::Director(Builder * pBuilder)
: m_pBuilder(pBuilder)
{
}
Director:: ~ Director()
{
delete m_pBuilder;
m_pBuilder = NULL;
}
// Construct 函数表示一个对象的整个构建过程,不同的部分之间的装配方式都是一致的,
// 首先构建PartA其次是PartB,只是根据不同的构建者会有不同的表示
void Director::Construct()
{
m_pBuilder -> BuilderPartA();
m_pBuilder -> BuilderPartB();
}
3)Main.cpp
/* ***********************************************************
********
created: 2006/07/20
filename: Main.cpp
PDF created with pdfFactory trial version www.pdffactory.com
author: 李创
http://www.cppblog.com/converse/
purpose: Builder模式的测试代码
****************************************************************
**** */
#include " Builder.h "
#include < stdlib.h >
int main()
{
Builder * pBuilder1 = new ConcreateBuilder1;
Director * pDirector1 = new Director(pBuilder1);
pDirector1 -> Construct();
Builder * pBuilder2 = new ConcreateBuilder2;
Director * pDirector2 = new Director(pBuilder2);
pDirector2 -> Construct();
delete pDirector1;
delete pDirector2;
system( " pause " );
return 0 ;
}
常见设计模式的解析和实现(C++)之四-Prototype模

作用:
用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。
UML结构图:
PDF created with pdfFactory trial version www.pdffactory.com
抽象基类:
1)Prototype:虚拟基类,所有原型的基类,提供Clone接口函数
接口函数:
1)Prototype::Clone函数:纯虚函数,根据不同的派生类来实例化创建对象.
解析:
Prototype模式其实就是常说的"虚拟构造函数"一个实现,C++的实现机制中并
没有支持这个特性,但是通过不同派生类实现的Clone接口函数可以完成与"虚
拟构造函数"同样的效果.举一个例子来解释这个模式的作用,假设有一家店铺是
配钥匙的,他对外提供配制钥匙的服务(提供Clone接口函数),你需要配什么钥
匙它不知道只是提供这种服务,具体需要配什么钥匙只有到了真正看到钥匙的原
型才能配好.也就是说,需要一个提供这个服务的对象,同时还需要一个原型(Prot
otype),不然不知道该配什么样的钥匙.
实现:
1)Prototype.h
/**************************************************************
******
created: 2006/07/20
filename: Prototype.h
author: 李创
http://www.cppblog.com/converse/
purpose: Prototype模式的演示代码
****************************************************************
*****/
#ifndef PROTOTYPE_H
#define PROTOTYPE_H
// 虚拟基类,所有原型的基类,提供Clone接口函数
PDF created with pdfFactory trial version www.pdffactory.com
class Prototype
{
public:
Prototype(){}
virtual ~Prototype(){}
virtual Prototype* Clone() = 0;
};
// 派生自Prototype,实现Clone方法
class ConcreatePrototype1
: public Prototype
{
public:
ConcreatePrototype1();
ConcreatePrototype1(const ConcreatePrototype1&);
virtual ~ConcreatePrototype1();
virtual Prototype* Clone();
};
// 派生自Prototype,实现Clone方法
class ConcreatePrototype2
: public Prototype
{
public:
ConcreatePrototype2();
ConcreatePrototype2(const ConcreatePrototype2&);
virtual ~ConcreatePrototype2();
virtual Prototype* Clone();
};
#endif
2)Prototype.cpp
/**************************************************************
******
created: 2006/07/20
filename: Prototype.cpp
author: 李创
http://www.cppblog.com/converse/
purpose: Prototype模式的演示代码
PDF created with pdfFactory trial version www.pdffactory.com
****************************************************************
*****/
#include "Prototype.h"
#include <iostream>
ConcreatePrototype1::ConcreatePrototype1()
{
std::cout << "construction of ConcreatePrototype1\n";
}
ConcreatePrototype1::~ConcreatePrototype1()
{
std::cout << "destruction of ConcreatePrototype1\n";
}
ConcreatePrototype1::ConcreatePrototype1(const ConcreatePrototype1&)
{
std::cout << "copy construction of ConcreatePrototype1\n";
}
Prototype* ConcreatePrototype1::Clone()
{
return new ConcreatePrototype1(*this);
}
ConcreatePrototype2::ConcreatePrototype2()
{
std::cout << "construction of ConcreatePrototype2\n";
}
ConcreatePrototype2::~ConcreatePrototype2()
{
std::cout << "destruction of ConcreatePrototype2\n";
}
ConcreatePrototype2::ConcreatePrototype2(const ConcreatePrototype2&)
{
std::cout << "copy construction of ConcreatePrototype2\n";
}
Prototype* ConcreatePrototype2::Clone()
{
PDF created with pdfFactory trial version www.pdffactory.com
return new ConcreatePrototype2(*this);
}
3)Main.cpp
/**************************************************************
******
created: 2006/07/20
filename: Main.cpp
author: 李创
http://www.cppblog.com/converse/
purpose: Prototype模式的测试代码
****************************************************************
*****/
#include "Prototype.h"
#include <stdlib.h>
int main()
{
Prototype* pPrototype1 = new ConcreatePrototype1();
Prototype* pPrototype2 = pPrototype1->Clone();
Prototype* pPrototype3 = new ConcreatePrototype2();
Prototype* pPrototype4 = pPrototype3->Clone();
delete pPrototype1;
delete pPrototype2;
delete pPrototype3;
delete pPrototype4;
system("pause");
return 0;
}
常见设计模式的解析和实现(C++)之五-Singleton模

PDF created with pdfFactory trial version www.pdffactory.com
作用:保证一个类仅有一个实例,并提供一个访问它的全局访问点。
UML结构图:
解析:
Singleton模式其实是对全局静态变量的一个取代策略,上面提到的Singleton
模式的两个作用在C++中是通过如下的机制实现的:1)仅有一个实例,提供一个
类的静态成员变量,大家知道类的静态成员变量对于一个类的所有对象而言是惟
一的2)提供一个访问它的全局访问点,也就是提供对应的访问这个静态成员变
量的静态成员函数,对类的所有对象而言也是惟一的.在C++中,可以直接使用类
域进行访问而不必初始化一个类的对象.
下面的实现其实是Singleton的一个简单实现,并不是特别的通用,一般的,如果
一个项目中需要使用到Singleton模式比较多的话,那么一般会实现一个Singl
eton的模板类,模板类的模板参数是需要采用Singleton模式的类,比如这样实
现:
template<typename T>
class Singleton
{
// .类的声明
};
// 需要采用singleton模式的类
class Test
: public Singleton<Test>
{
// 类的声明
};
但是,下面的实现还是采用最简单的实现办法,起的是演示的作用
实现:
1)Singleton.h
/**************************************************************
******
PDF created with pdfFactory trial version www.pdffactory.com
created: 2006/07/20
filename: Singleton.h
author: 李创
http://www.cppblog.com/converse/
purpose: Singleton 模式的演示代码
****************************************************************
*****/
#ifndef SINGLETON_H
#define SINGLETON_H
class Singleton
{
public:
Singleton(){};
~Singleton(){};
// 静态成员函数,提供全局访问的接口
static Singleton* GetInstancePtr();
static Singleton GetInstance();
void Test();
private:
// 静态成员变量,提供全局惟一的一个实例
static Singleton* m_pStatic;
};
#endif
2)Singleton.cpp
/**************************************************************
******
created: 2006/07/20
filename: Singleton.cpp
author: 李创
http://www.cppblog.com/converse/
purpose: Singleton 模式的演示代码
****************************************************************
*****/
#include "Singleton.h"
PDF created with pdfFactory trial version www.pdffactory.com
#include <iostream>
// 类的静态成员变量要在类体外进行定义
Singleton* Singleton::m_pStatic = NULL;
Singleton* Singleton::GetInstancePtr()
{
if (NULL == m_pStatic)
{
m_pStatic = new Singleton();
}
return m_pStatic;
}
Singleton Singleton::GetInstance()
{
return *GetInstancePtr();
}
void Singleton::Test()
{
std::cout << "Test!\n";
}
3)Main.cpp
/**************************************************************
******
created: 2006/07/20
filename: Main.cpp
author: 李创
http://www.cppblog.com/converse/
purpose: Singleton 模式的测试代码
****************************************************************
*****/
#include "Singleton.h"
#include <stdlib.h>
int main()
{
// 不用初始化类对象就可以访问了
Singleton::GetInstancePtr()->Test();
PDF created with pdfFactory trial version www.pdffactory.com
Singleton::GetInstance().Test();
system("pause");
return 0;
}
常见设计模式的解析和实现(C++)之六-Adapt模式
作用:
将一个类的接口转换成客户希望的另外一个接口。Adapt 模式使得原本由于接
口不兼容而不能一起工作的那些类可以一起工作。
UML示意图
1)采用继承原有接口类的方式
2)采用组合原有接口类的方式
解析:
Adapt模式其实就是把完成同样的一个功能但是接口不能兼容的类桥接在一起
使之可以在一起工作,这个模式使得复用旧的接口成为可能.
PDF created with pdfFactory trial version www.pdffactory.com
实现:
Adapt模式有两种实现办法,一种是采用继承原有接口类的方法,一种是采用组
合原有接口类的方法,这里采用的是第二种实现方法.
1)Adapt.h
/**************************************************************
******
created: 2006/07/20
filename: Adapter.h
author: 李创
http://www.cppblog.com/converse/
purpose: Adapter模式的演示代码
****************************************************************
*****/
#ifndef ADAPTER_H
#define ADAPTER_H
// 需要被Adapt 的类
class Target
{
public:
Target(){}
virtual ~Target() {}
virtual void Request() = 0;
};
// 与被Adapt对象提供不兼容接口的类
class Adaptee
{
public:
Adaptee(){}
~Adaptee(){}
void SpecialRequest();
};
// 进行Adapt的类,采用聚合原有接口类的方式
class Adapter
: public Target
{
public:
Adapter(Adaptee* pAdaptee);
PDF created with pdfFactory trial version www.pdffactory.com
virtual ~Adapter();
virtual void Request();
private:
Adaptee* m_pAdptee;
};
#endif
2)Adapt.cpp
/**************************************************************
******
created: 2006/07/20
filename: Adapter.cpp
author: 李创
http://www.cppblog.com/converse/
purpose: Adapter模式的演示代码
****************************************************************
*****/
#include "Adapter.h"
#include <iostream>
void Adaptee::SpecialRequest()
{
std::cout << "SpecialRequest of Adaptee\n";
}
Adapter::Adapter(Adaptee* pAdaptee)
: m_pAdptee(pAdaptee)
{
}
Adapter::~Adapter()
{
delete m_pAdptee;
m_pAdptee = NULL;
}
void Adapter::Request()
{
PDF created with pdfFactory trial version www.pdffactory.com
std::cout << "Request of Adapter\n";
m_pAdptee->SpecialRequest();
}
3)Main.cpp
/**************************************************************
******
created: 2006/07/20
filename: Main.cpp
author: 李创
http://www.cppblog.com/converse/
purpose: Adapter模式的测试代码
****************************************************************
*****/
#include "Adapter.h"
#include <stdlib.h>
int main()
{
Adaptee *pAdaptee = new Adaptee;
Target *pTarget = new Adapter(pAdaptee);
pTarget->Request();
delete pTarget;
system("pause");
return 0;
}
常见设计模式的解析和实现(C++)之七-Bridge模式
作用:
将抽象部分与它的实现部分分离,使它们都可以独立地变化。
UML结构图:
PDF created with pdfFactory trial version www.pdffactory.com
抽象基类:
1)Abstraction:某个抽象类,它的实现方式由Implementor完成.
2)Implementor:实现类的抽象基类,定义了实现Abastraction的基本操作,而
它的派生类实现这些接口.
接口函数:
1)Implementor::OperationImpl:定义了为实现Abstraction需要的基本操
作,由Implementor的派生类实现之,而在Abstraction::Operation函数中根
据不同的指针多态调用这个函数.
解析:
Bridge用于将表示和实现解耦,两者可以独立的变化.在Abstraction类中维护
一个Implementor类指针,需要采用不同的实现方式的时候只需要传入不同的
Implementor派生类就可以了.
Bridge的实现方式其实和Builde十分的相近,可以这么说:本质上是一样的,只
是封装的东西不一样罢了.两者的实现都有如下的共同点:抽象出来一个基类,这
个基类里面定义了共有的一些行为,形成接口函数(对接口编程而不是对实现编
程),这个接口函数在Buildier中是BuildePart函数在Bridge中是Operation
Impl 函数;其次,聚合一个基类的指针,如Builder模式中Director类聚合了一
个Builder基类的指针,而Brige模式中Abstraction类聚合了一个Impleme
ntor基类的指针(优先采用聚合而不是继承);而在使用的时候,都把对这个类的
使用封装在一个函数中,在Bridge中是封装在Director::Construct函数中,因
为装配不同部分的过程是一致的,而在Bridge模式中则是封装在Abstraction::
Operation函数中,在这个函数中调用对应的Implementor::OperationImpl
函数.就两个模式而言,Builder封装了不同的生成组成部分的方式,而Bridge封
装了不同的实现方式.
因此,如果以一些最基本的面向对象的设计原则来分析这些模式的实现的话,还
是可以看到很多共同的地方的.
PDF created with pdfFactory trial version www.pdffactory.com
实现:
1)Bridge.h
/**************************************************************
******
created: 2006/07/20
filename: Brige.h
author: 李创
http://www.cppblog.com/converse/
purpose: Brige模式的演示代码
****************************************************************
*****/
#ifndef BRIDEG_H
#define BRIDEG_H
class Implementor;
// 维护一个Implementor类的指针
class Abstraction
{
public:
Abstraction(Implementor* pImplementor);
virtual ~Abstraction();
void Operation();
protected:
Implementor* m_pImplementor;
};
// 为实现Abstraction 定义的抽象基类,定义了实现的接口函数
class Implementor
{
public:
Implementor(){}
virtual ~Implementor(){}
virtual void OperationImpl() = 0;
};
// 继承自Implementor,是Implementor的不同实现之一
class ConcreateImplementorA
PDF created with pdfFactory trial version www.pdffactory.com
: public Implementor
{
public:
ConcreateImplementorA(){}
virtual ~ConcreateImplementorA(){}
virtual void OperationImpl();
};
// 继承自Implementor,是Implementor的不同实现之一
class ConcreateImplementorB
: public Implementor
{
public:
ConcreateImplementorB(){}
virtual ~ConcreateImplementorB(){}
virtual void OperationImpl();
};
#endif
2)Bridge.cpp
/**************************************************************
******
created: 2006/07/20
filename: Brige.cpp
author: 李创
http://www.cppblog.com/converse/
purpose: Brige模式的演示代码
****************************************************************
*****/
#include "Brige.h"
#include <iostream>
void ConcreateImplementorA::OperationImpl()
{
std::cout << "Implementation by ConcreateImplementorA\n";
}
void ConcreateImplementorB::OperationImpl()
{
PDF created with pdfFactory trial version www.pdffactory.com
std::cout << "Implementation by ConcreateImplementorB\n";
}
Abstraction::Abstraction(Implementor* pImplementor)
: m_pImplementor(pImplementor)
{
}
Abstraction::~Abstraction()
{
delete m_pImplementor;
m_pImplementor = NULL;
}
void Abstraction::Operation()
{
m_pImplementor->OperationImpl();
}
3)Main.cpp
/**************************************************************
******
created: 2006/07/20
filename: Main.cpp
author: 李创
http://www.cppblog.com/converse/
purpose: Bridge模式的测试代码
****************************************************************
*****/
#include "Brige.h"
#include <stdlib.h>
int main()
{
ConcreateImplementorA *pImplA = new ConcreateImplementorA();
Abstraction *pAbstraction1 = new Abstraction(pImplA);
pAbstraction1->Operation();
ConcreateImplementorB *pImplB = new ConcreateImplementorB();
Abstraction *pAbstraction2 = new Abstraction(pImplB);
pAbstraction2->Operation();
PDF created with pdfFactory trial version www.pdffactory.com
delete pAbstraction1;
delete pAbstraction2;
system("pause");
return 0;
}
常见设计模式的解析和实现(C++)之八-Composite模

作用:
将对象组合成树形结构以表示“部分-整体”的层次结构。Composite使得用户对
单个对象和组合对象的使用具有一致性。
UML结构图:
抽象基类:
1)Component:为组合中的对象声明接口,声明了类共有接口的缺省行为(如这
里的Add,Remove,GetChild函数),声明一个接口函数可以访问Component
的子组件.
接口函数:
1)Component::Operatation:定义了各个组件共有的行为接口,由各个组件的
具体实现.
2)Component::Add添加一个子组件
PDF created with pdfFactory trial version www.pdffactory.com
3)Component::Remove::删除一个子组件.
4)Component::GetChild:获得子组件的指针.
解析:
Component模式是为解决组件之间的递归组合提供了解决的办法,它主要分为
两个派生类,其中的Leaf是叶子结点,也就是不含有子组件的结点,而Composit
e是含有子组件的类.举一个例子来说明这个模式,在UI的设计中,最基本的控件
是诸如Button,Edit这样的控件,相当于是这里的Leaf组件,而比较复杂的控件
比如List则可也看做是由这些基本的组件组合起来的控件,相当于这里的Comp
osite,它们之间有一些行为含义是相同的,比如在控件上作一个点击,移动操作等
等的,这些都可以定义为抽象基类中的接口虚函数,由各个派生类去实现之,这些
都会有的行为就是这里的Operation函数,而添加,删除等进行组件组合的操作
只有非叶子结点才可能有,所以虚拟基类中只是提供接口而且默认的实现是什么
都不做.
实现:
1)Composite.h
/**************************************************************
******
created: 2006/07/20
filename: Composite.h
author: 李创
http://www.cppblog.com/converse/
purpose: Composite模式的演示代码
****************************************************************
*****/
#ifndef COMPOSITE_H
#define COMPOSITE_H
#include <list>
// 组合中的抽象基类
class Component
{
public:
Component(){}
virtual ~Component(){}
// 纯虚函数,只提供接口,没有默认的实现
virtual void Operation() = 0;
// 虚函数,提供接口,有默认的实现就是什么都不做
PDF created with pdfFactory trial version www.pdffactory.com
virtual void Add(Component* pChild);
virtual void Remove(Component* pChild);
virtual Component* GetChild(int nIndex);
};
// 派生自Component,是其中的叶子组件的基类
class Leaf
: public Component
{
public:
Leaf(){}
virtual ~Leaf(){}
virtual void Operation();
};
// 派生自Component,是其中的含有子件的组件的基类
class Composite
: public Component
{
public:
Composite(){}
virtual ~Composite();
virtual void Operation();
virtual void Add(Component* pChild);
virtual void Remove(Component* pChild);
virtual Component* GetChild(int nIndex);
private:
// 采用list容器去保存子组件
std::list<Component*> m_ListOfComponent;
};
#endif
2)Composite.cpp
/**************************************************************
******
created: 2006/07/20
filename: Composite.cpp
author: 李创
http://www.cppblog.com/converse/
PDF created with pdfFactory trial version www.pdffactory.com
purpose: Composite模式的演示代码
****************************************************************
*****/
#include "Composite.h"
#include <iostream>
#include <algorithm>
/*-------------------------------------------------------------------
Component成员函数的实现
-------------------------------------------------------------------*/
void Component::Add(Component* pChild)
{
}
void Component::Remove(Component* pChild)
{
}
Component* Component::GetChild(int nIndex)
{
return NULL;
}
/*-------------------------------------------------------------------
Leaf成员函数的实现
-------------------------------------------------------------------*/
void Leaf::Operation()
{
std::cout << "Operation by leaf\n";
}
/*-------------------------------------------------------------------
Composite成员函数的实现
-------------------------------------------------------------------*/
Composite::~Composite()
{
std::list<Component*>::iterator iter1, iter2, temp;
PDF created with pdfFactory trial version www.pdffactory.com
for (iter1 = m_ListOfComponent.begin(), iter2 = m_ListOfComponent.end();
iter1 != iter2;
)
{
temp = iter1;
++iter1;
delete (*temp);
}
}
void Composite::Add(Component* pChild)
{
m_ListOfComponent.push_back(pChild);
}
void Composite::Remove(Component* pChild)
{
std::list<Component*>::iterator iter;
iter = find(m_ListOfComponent.begin(), m_ListOfComponent.end(), pChild);
if (m_ListOfComponent.end() != iter)
{
m_ListOfComponent.erase(iter);
}
}
Component* Composite::GetChild(int nIndex)
{
if (nIndex <= 0 || nIndex > m_ListOfComponent.size())
return NULL;
std::list<Component*>::iterator iter1, iter2;
int i;
for (i = 1, iter1 = m_ListOfComponent.begin(), iter2 = m_ListOfComponent.
end();
iter1 != iter2;
++iter1, ++i)
{
if (i == nIndex)
break;
}
PDF created with pdfFactory trial version www.pdffactory.com
return *iter1;
}
void Composite::Operation()
{
std::cout << "Operation by Composite\n";
std::list<Component*>::iterator iter1, iter2;
for (iter1 = m_ListOfComponent.begin(), iter2 = m_ListOfComponent.end();
iter1 != iter2;
++iter1)
{
(*iter1)->Operation();
}
}
3)Main.cpp
/**************************************************************
******
created: 2006/07/20
filename: Main.cpp
author: 李创
http://www.cppblog.com/converse/
purpose: Composite模式的测试代码
****************************************************************
*****/
#include "Composite.h"
#include <stdlib.h>
int main()
{
Leaf *pLeaf1 = new Leaf();
Leaf *pLeaf2 = new Leaf();
Composite* pComposite = new Composite;
pComposite->Add(pLeaf1);
pComposite->Add(pLeaf2);
pComposite->Operation();
pComposite->GetChild(2)->Operation();
delete pComposite;
PDF created with pdfFactory trial version www.pdffactory.com
system("pause");
return 0;
}
常见设计模式的解析和实现(C++)之九-Decorator模

作用:
动态地给一个对象添加一些额外的职责。就增加功能来说,Decorator 模式相
比生成子类更为灵活。
UML结构图:
抽象基类:
1)Component:定义一个对象接口,可以为这个接口动态的添加职责.
2)Decorator:维持一个指向Component的指针,并且有一个和Component
一致的接口函数.
接口函数:
1)Component::Operation:这个接口函数由Component声明,因此Compo
nent的派生类都需要实现,可以在这个接口函数的基础上给它动态添加职责.
解析:
Decorator的派生类可以为ConcreateComponent类的对象动态的添加职责,
PDF created with pdfFactory trial version www.pdffactory.com
或者可以这么说:Decorator的派生类装饰ConcreateComponent类的对象.
具体是这么实现的,首先初始化一个ConcreateComponent类的对象(被装饰
者),采用这个对象去生成一个Decorator对象(装饰者),之后对Operation函数
的调用则是对这个Decorator对象成员函数的多态调用.这里的实现要点是De
corator类和ConcreateComponent类都继承自Component,从而两者的接
口函数是一致的;其次,Decorator维护了一个指向Component的指针,从而可
以实现对Component::Operation函数的动态调用.
实现:
1)Decorator.h
/**************************************************************
******
created: 2006/07/20
filename: Decorator.h
author: 李创
http://www.cppblog.com/converse/
purpose: Decorator模式的演示代码
****************************************************************
*****/
#ifndef DECORATOR_H
#define DECORATOR_H
// 抽象基类,定义一个对象接口,可以为这个接口动态的添加职责.
class Component
{
public:
Component(){}
virtual ~Component(){}
// 纯虚函数,由派生类实现
virtual void Operation() = 0;
};
// 抽象基类,维护一个指向Component 对象的指针
class Decorator
: public Component
{
public:
Decorator(Component* pComponent) : m_pComponent(pComponent){}
virtual ~Decorator();
protected:
PDF created with pdfFactory trial version www.pdffactory.com
Component* m_pComponent;
};
// 派生自Component,在这里表示需要给它动态添加职责的类
class ConcreateComponent
: public Component
{
public:
ConcreateComponent(){}
virtual ~ConcreateComponent(){}
virtual void Operation();
};
// 派生自Decorator,这里代表为ConcreateComponent动态添加职责的类
class ConcreateDecorator
: public Decorator
{
public:
ConcreateDecorator(Component* pComponent) : Decorator(pComponent){}
virtual ~ConcreateDecorator(){}
virtual void Operation();
private:
void AddedBehavior();
};
#endif
2)Decorator.cpp
/**************************************************************
******
created: 2006/07/20
filename: Decorator.cpp
author: 李创
http://www.cppblog.com/converse/
purpose: Decorator模式的演示代码
****************************************************************
*****/
#include "Decorator.h"
#include <iostream>
PDF created with pdfFactory trial version www.pdffactory.com
Decorator::~Decorator()
{
delete m_pComponent;
m_pComponent = NULL;
}
void ConcreateComponent::Operation()
{
std::cout << "Operation of ConcreateComponent\n";
}
void ConcreateDecorator::Operation()
{
m_pComponent->Operation();
AddedBehavior();
}
void ConcreateDecorator::AddedBehavior()
{
std::cout << "AddedBehavior of ConcreateDecorator\n";
}
3)Main.cpp
/**************************************************************
******
created: 2006/07/20
filename: Main.cpp
author: 李创
http://www.cppblog.com/converse/
purpose: Decorator模式的测试代码
****************************************************************
*****/
#include "Decorator.h"
#include <stdlib.h>
int main()
{
// 初始化一个Component对象
Component* pComponent = new ConcreateComponent();
// 采用这个Component对象去初始化一个Decorator对象,
// 这样就可以为这个Component对象动态添加职责
PDF created with pdfFactory trial version www.pdffactory.com
Decorator* pDecorator = new ConcreateDecorator(pComponent);
pDecorator->Operation();
delete pDecorator;
system("pause");
return 0;
}
常见设计模式的解析和实现(C++)之十-Proxy模式
作用:
为其他对象提供一种代理以控制对这个对象的访问。
UML结构图:
抽象基类:
1)Subject:定义了Proxy和RealSubject的公有接口,这样就可以在任何需要
使用到RealSubject的地方都使用Proxy.
解析:
Proxy其实是基于这样一种时常使用到的技术-某个对象直到它真正被使用到的
时候才被初始化,在没有使用到的时候就暂时用Proxy作一个占位符.这个模式
实现的要点就是Proxy和RealSubject都继承自Subject,这样保证了两个的
接口都是一致的.
PDF created with pdfFactory trial version www.pdffactory.com
实现:
1)Proxy.h
/**************************************************************
******
created: 2006/07/26
filename: Proxy.h
author: 李创
http://www.cppblog.com/converse/
purpose: Proxy模式的演示代码
****************************************************************
*****/
#ifndef PROXY_H
#define PROXY_H
// 定义了Proxy和RealSubject的公有接口,
// 这样就可以在任何需要使用到RealSubject的地方都使用Proxy.
class Subject
{
public:
Subject(){}
virtual ~Subject(){}
virtual void Request() = 0;
};
// 真正使用的实体
class RealSubject
: public Subject
{
public:
RealSubject();
virtual ~RealSubject(){}
virtual void Request();
};
// 代理类,含有一个指向RealSubject对象的指针
class Proxy
: public Subject
{
public:
Proxy();
PDF created with pdfFactory trial version www.pdffactory.com
virtual ~Proxy();
virtual void Request();
private:
RealSubject* m_pRealSubject;
};
#endif
2)Proxy.cpp
/**************************************************************
******
created: 2006/07/26
filename: Proxy.cpp
author: 李创
http://www.cppblog.com/converse/
purpose: Proxy模式的演示代码
****************************************************************
*****/
#include "Proxy.h"
#include <iostream>
RealSubject::RealSubject()
{
std::cout << "Constructing a RealSubject\n";
}
void RealSubject::Request()
{
std::cout << "Request By RealSubject\n";
}
Proxy::Proxy()
: m_pRealSubject(NULL)
{
std::cout << "Constructing a Proxy\n";
}
Proxy::~Proxy()
{
delete m_pRealSubject;
m_pRealSubject = NULL;
PDF created with pdfFactory trial version www.pdffactory.com
}
void Proxy::Request()
{
// 需要使用RealSubject 的时候才去初始化
if (NULL == m_pRealSubject)
{
std::cout << "Request By Proxy\n";
m_pRealSubject = new RealSubject();
}
m_pRealSubject->Request();
}
3)Main.cpp
/**************************************************************
******
created: 2006/07/26
filename: Main.cpp
author: 李创
http://www.cppblog.com/converse/
purpose: Proxy模式的测试代码
****************************************************************
*****/
#include "Proxy.h"
#include <stdlib.h>
int main()
{
Subject* pProxy = new Proxy();
pProxy->Request();
delete pProxy;
system("pause");
return 0;
}
PDF created with pdfFactory trial version www.pdffactory.com
常见设计模式的解析和实现(C++)之十一-Template
Method模式
作用:
定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。TemplateMetho
d 使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。
UML结构图:
抽象基类:
1)AbstractClass:抽象基类,定义算法的轮廓
解析:
TemplateMethod 的关键在于在基类中定义了一个算法的轮廓,但是算法每一
步具体的实现留给了派生类.但是这样也会造成设计的灵活性不高的缺点,因为
轮廓已经定下来了要想改变就比较难了,这也是为什么优先采用聚合而不是继承
的原因.
实现:
1)TemplateMethod.h
/**************************************************************
******
created: 2006/07/20
filename: TemplateMethod.h
author: 李创
http://www.cppblog.com/converse/
purpose: TemplateMethod模式的演示代码
****************************************************************
*****/
PDF created with pdfFactory trial version www.pdffactory.com
// 抽象基类,定义算法的轮廓
class AbstractClass
{
public:
AbstractClass(){}
virtual ~AbstractClass(){}
// 这个函数中定义了算法的轮廓
void TemplateMethod();
protected:
// 纯虚函数,由派生类实现之
virtual void PrimitiveOperation1() = 0;
virtual void PrimitiveOperation2() = 0;
};
// 继承自AbstractClass,实现算法
class ConcreateClass
: public AbstractClass
{
public:
ConcreateClass(){}
virtual ~ConcreateClass(){}
protected:
virtual void PrimitiveOperation1();
virtual void PrimitiveOperation2();
};
2)TemplateMethod.cpp
/**************************************************************
******
created: 2006/07/20
filename: TemplateMethod.cpp
author: 李创
http://www.cppblog.com/converse/
purpose: TemplateMethod模式的演示代码
****************************************************************
*****/
#include "TemplateMethod.h"
#include <iostream>
PDF created with pdfFactory trial version www.pdffactory.com
void AbstractClass::TemplateMethod()
{
PrimitiveOperation1();
PrimitiveOperation2();
}
void ConcreateClass::PrimitiveOperation1()
{
std::cout << "PrimitiveOperation1 by ConcreateClass\n";
}
void ConcreateClass::PrimitiveOperation2()
{
std::cout << "PrimitiveOperation2 by ConcreateClass\n";
}
3)Main.cpp
/**************************************************************
******
created: 2006/07/20
filename: Main.cpp
author: 李创
http://www.cppblog.com/converse/
purpose: TemplateMethod模式的测试代码
****************************************************************
*****/
#include "TemplateMethod.h"
#include <stdlib.h>
int main()
{
AbstractClass* pConcreateClass = new ConcreateClass;
pConcreateClass->TemplateMethod();
delete pConcreateClass;
system("pause");
return 0;
}
PDF created with pdfFactory trial version www.pdffactory.com
常见设计模式的解析和实现(C++)之十二-ChainOfRe
sponsibility模式
作用:
使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系.
将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止.
UML结构图:
抽象基类:
1)Handler:定义一个处理请求的接口,在图中这个接口就是HandleRequset函
数,这个类同时有一个指向Handler对象的指针,指向后续的处理请求的对象(如
果有的话).
解析:
这个模式把可以处理一个请求的对象以链的形式连在了一起,让这些对象都有处
理请求的机会.好比原来看古装电视中经常看到皇宫中召见某人的时候,太监们
(可以处理一个请求的对象)就会依次的喊:传XX...这样一直下去直到找到这个
人为止.ChainOfResponsibility模式也是这样的处理请求的,如果有后续的对
象可以处理,那么传给后续的对象处理,否则就自己处理请求.这样的设计把请求
的发送者和请求这种的处理者解耦了,好比发号的皇帝不知道到底是哪个太监最
后会找到他要找到的人一般,只管发出命令就OK了.
实现:
1)ChainOfResponsibility.h
/**************************************************************
******
created: 2006/07/20
PDF created with pdfFactory trial version www.pdffactory.com
filename: ChainOfResponsibility.h
author: 李创
http://www.cppblog.com/converse/
purpose: ChainOfResponsibility模式的演示代码
****************************************************************
*****/
#ifndef CHAINOFRESPONSIBILITY_H
#define CHAINOFRESPONSIBILITY_H
#include <stdio.h>
// 抽象基类,定义一个处理请求的接口
class Handler
{
public:
Handler(Handler *pSuccessor = NULL);
virtual ~Handler();
// 纯虚函数,由派生类实现
virtual void HandleRequset() = 0;
protected:
Handler* m_pSuccessor;
};
class ConcreateHandler1
: public Handler
{
public:
ConcreateHandler1(Handler *pSuccessor = NULL) : Handler(pSuccessor){}
virtual ~ConcreateHandler1(){}
virtual void HandleRequset();
};
class ConcreateHandler2
: public Handler
{
public:
ConcreateHandler2(Handler *pSuccessor = NULL) : Handler(pSuccessor){}
virtual ~ConcreateHandler2(){}
PDF created with pdfFactory trial version www.pdffactory.com
virtual void HandleRequset();
};
#endif
2)ChainOfResponsibility.cpp
/**************************************************************
******
created: 2006/07/20
filename: ChainOfResponsibility.cpp
author: 李创
http://www.cppblog.com/converse/
purpose: ChainOfResponsibility模式的演示代码
****************************************************************
*****/
#include "ChainOfResponsibility.h"
#include <iostream>
Handler::Handler(Handler *pSuccessor /* = NULL*/)
: m_pSuccessor(pSuccessor)
{
}
Handler::~Handler()
{
delete m_pSuccessor;
m_pSuccessor = NULL;
}
void ConcreateHandler1::HandleRequset()
{
if (NULL != m_pSuccessor)
{
m_pSuccessor->HandleRequset();
}
else
{
std::cout << "HandleRequset by ConcreateHandler1\n";
}
}
PDF created with pdfFactory trial version www.pdffactory.com
void ConcreateHandler2::HandleRequset()
{
if (NULL != m_pSuccessor)
{
m_pSuccessor->HandleRequset();
}
else
{
std::cout << "HandleRequset by ConcreateHandler2\n";
}
}
3)Main.cpp
/**************************************************************
******
created: 2006/07/20
filename: Main.cpp
author: 李创
http://www.cppblog.com/converse/
purpose: ChainOfResponsibility模式的测试代码
****************************************************************
*****/
#include "ChainOfResponsibility.h"
#include <stdlib.h>
int main()
{
Handler *p1 = new ConcreateHandler1();
Handler *p2 = new ConcreateHandler2(p1);
p2->HandleRequset();
delete p2;
system("pause");
return 0;
}
PDF created with pdfFactory trial version www.pdffactory.com
常见设计模式的解析和实现(C++)之十三-FlyWeight
模式
作用:
运用共享技术有效地支持大量细粒度的对象。
UML结构图:
解析:
Flyweight模式在大量使用一些可以被共享的对象的时候经常使用.比如,在QQ
聊天的时候很多时候你懒得回复又不得不回复的时候,一般会用一些客套的话语
敷衍别人,如"呵呵","好的"等等之类的,这些简单的答复其实每个人都是提前定
义好的,在使用的时候才调用出来.Flyweight就是基于解决这种问题的思路而
产生的,当需要一个可以在其它地方共享使用的对象的时候,先去查询是否已经
存在了同样的对象,如果没有就生成之有的话就直接使用.因此,Flyweight模式
和Factory模式也经常混用.
实现:
需要说明的是下面的实现仅仅实现了对可共享对象的使用,非可共享对象的使用
没有列出,因为这个不是Flyweight模式的重点.这里的实现要点是采用一个list
链表来保存这些可以被共享的对象,需要使用的时候就到链表中查询是不是已经
存在了,如果不存在就初始化一个,然后返回这个对象的指针.
PDF created with pdfFactory trial version www.pdffactory.com
1)Flyweight.h
/**************************************************************
******
created: 2006/07/26
filename: FlyWeight.h
author: 李创
http://www.cppblog.com/converse/
purpose: FlyWeight模式的演示代码
****************************************************************
*****/
#ifndef FLYWEIGHT_H
#define FLYWEIGHT_H
#include <string>
#include <list>
typedef std::string STATE;
class Flyweight
{
public:
virtual ~Flyweight(){}
STATE GetIntrinsicState();
virtual void Operation(STATE& ExtrinsicState) = 0;
protected:
Flyweight(const STATE& state)
:m_State(state)
{
}
private:
STATE m_State;
};
class FlyweightFactory
{
public:
FlyweightFactory(){}
~FlyweightFactory();
PDF created with pdfFactory trial version www.pdffactory.com
Flyweight* GetFlyweight(const STATE& key);
private:
std::list<Flyweight*> m_listFlyweight;
};
class ConcreateFlyweight
: public Flyweight
{
public:
ConcreateFlyweight(const STATE& state)
: Flyweight(state)
{
}
virtual ~ConcreateFlyweight(){}
virtual void Operation(STATE& ExtrinsicState);
};
#endif
2)Flyweight.cpp
/**************************************************************
******
created: 2006/07/26
filename: FlyWeight.cpp
author: 李创
http://www.cppblog.com/converse/
purpose: FlyWeight模式的演示代码
****************************************************************
*****/
#include "FlyWeight.h"
#include <iostream>
inline STATE Flyweight::GetIntrinsicState()
{
return m_State;
}
FlyweightFactory::~FlyweightFactory()
PDF created with pdfFactory trial version www.pdffactory.com
{
std::list<Flyweight*>::iterator iter1, iter2, temp;
for (iter1 = m_listFlyweight.begin(), iter2 = m_listFlyweight.end();
iter1 != iter2;
)
{
temp = iter1;
++iter1;
delete (*temp);
}
m_listFlyweight.clear();
}
Flyweight* FlyweightFactory::GetFlyweight(const STATE& key)
{
std::list<Flyweight*>::iterator iter1, iter2;
for (iter1 = m_listFlyweight.begin(), iter2 = m_listFlyweight.end();
iter1 != iter2;
++iter1)
{
if ((*iter1)->GetIntrinsicState() == key)
{
std::cout << "The Flyweight:" << key << " already exits"<< std::endl;
return (*iter1);
}
}
std::cout << "Creating a new Flyweight:" << key << std::endl;
Flyweight* flyweight = new ConcreateFlyweight(key);
m_listFlyweight.push_back(flyweight);
}
void ConcreateFlyweight::Operation(STATE& ExtrinsicState)
{
}
3)Main.cpp
/**************************************************************
******
PDF created with pdfFactory trial version www.pdffactory.com
created: 2006/07/26
filename: Main.cpp
author: 李创
http://www.cppblog.com/converse/
purpose: FlyWeight模式的测试代码
****************************************************************
*****/
#include "FlyWeight.h"
int main()
{
FlyweightFactory flyweightfactory;
flyweightfactory.GetFlyweight("hello");
flyweightfactory.GetFlyweight("world");
flyweightfactory.GetFlyweight("hello");
system("pause");
return 0;
}
常见设计模式的解析和实现(C++)之十四-Command
模式
作用:
将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化;对请
求排队或记录请求日志,以及支持可撤消的操作.
UML结构图:
PDF created with pdfFactory trial version www.pdffactory.com
解析:
Comnand模式的思想是把命令封装在一个类中,就是这里的Command基类,
同时把接收对象也封装在一个类中就是这里的Receiver类中,由调用这个命令
的类也就是这里的Invoker类来调用.其实,如果弄清楚了Command模式的原
理,就会发现其实它和注册回调函数的原理是很相似的,而在面向过程的设计中
的回调函数其实和这里的Command类的作用是一致的.采用Command模式
解耦了命令的发出者和命令的执行者.
实现:
1)Command.h
/**************************************************************
******
created: 2006/08/04
filename: Command.h
author: 李创
http://www.cppblog.com/converse/
purpose: Command模式的演示代码
****************************************************************
*****/
#ifndef COMMAND_H
#define COMMAND_H
class Command
{
public:
virtual ~Command() {}
virtual void Execute() = 0;
};
class Receiver
{
public:
void Action();
};
class Invoker
{
public:
Invoker(Command *pCommand);
~Invoker();
PDF created with pdfFactory trial version www.pdffactory.com
void Invoke();
private:
Command *m_pCommand;
};
class ConcreateComand
: public Command
{
public:
ConcreateComand(Receiver* pReceiver);
virtual ~ConcreateComand();
virtual void Execute();
private:
Receiver* m_pReceiver;
};
#endif
2)Command.cpp
/**************************************************************
******
created: 2006/08/04
filename: Command.cpp
author: 李创
http://www.cppblog.com/converse/
purpose: Command模式的演示代码
****************************************************************
*****/
#include "Command.h"
#include <iostream>
void Receiver::Action()
{
std::cout << "Receiver Action\n";
}
Invoker::Invoker(Command *pCommand)
: m_pCommand(pCommand)
PDF created with pdfFactory trial version www.pdffactory.com
{
}
Invoker::~Invoker()
{
delete m_pCommand;
m_pCommand = NULL;
}
void Invoker::Invoke()
{
if (NULL != m_pCommand)
{
m_pCommand->Execute();
}
}
ConcreateComand::ConcreateComand(Receiver* pReceiver)
: m_pReceiver(pReceiver)
{
}
ConcreateComand::~ConcreateComand()
{
delete m_pReceiver;
m_pReceiver = NULL;
}
void ConcreateComand::Execute()
{
if (NULL != m_pReceiver)
{
m_pReceiver->Action();
}
std::cout << "Execute by ConcreateComand\n";
}
3)Main.cpp
/**************************************************************
******
PDF created with pdfFactory trial version www.pdffactory.com
created: 2006/08/04
filename: main.cpp
author: 李创
http://www.cppblog.com/converse/
purpose: Command模式的测试代码
****************************************************************
*****/
#include "Command.h"
#include <stdlib.h>
int main()
{
Receiver* pReceiver = new Receiver();
Command* pCommand = new ConcreateComand(pReceiver);
Invoker* pInvoker = new Invoker(pCommand);
pInvoker->Invoke();
delete pInvoker;
system("pause");
return 0;
}
常见设计模式的解析和实现(C++)之十五-Observer
模式
作用:
定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖
于它的对象都得到通知并被自动更新.
UML结构图:
PDF created with pdfFactory trial version www.pdffactory.com
解析:
Observer模式定义的是一种一对多的关系,这里的一就是图中的Subject类,
而多则是Obesrver类,当Subject类的状态发生变化的时候通知与之对应的O
besrver类们也去相应的更新状态,同时支持动态的添加和删除Observer对象
的功能.Obesrver模式的实现要点是,第一一般subject类都是采用链表等容器
来存放Observer对象,第二抽取出Observer对象的一些公共的属性形成Obs
erver基类,而Subject中保存的则是Observer类对象的指针,这样就使Subj
ect和具体的Observer实现了解耦,也就是Subject不需要去关心到底是哪个
Observer对放进了自己的容器中.生活中有很多例子可以看做是Observer模
式的运用,比方说,一个班有一个班主任(Subject),他管理手下的一帮学生(Obs
erver),当班里有一些事情发生需要通知学生的时候,班主任要做的不是逐个学
生挨个的通知而是把学生召集起来一起通知,实现了班主任和具体学生的关系解
耦.
实现:
1)Observer.h
/**************************************************************
******
created: 2006/07/20
filename: Observer.h
author: 李创
http://www.cppblog.com/converse/
purpose: Observer模式的演示代码
****************************************************************
*****/
#ifndef OBSERVER_H
#define OBSERVER_H
PDF created with pdfFactory trial version www.pdffactory.com
#include <list>
typedef int STATE;
class Observer;
// Subject 抽象基类,只需要知道Observer基类的声明就可以了
class Subject
{
public:
Subject() : m_nSubjectState(-1){}
virtual ~Subject();
void Notify(); // 通知对象改变状态
void Attach(Observer *pObserver); // 新增对象
void Detach(Observer *pObserver); // 删除对象
// 虚函数,提供默认的实现,派生类可以自己实现来覆盖基类的实现
virtual void SetState(STATE nState); // 设置状态
virtual STATE GetState(); // 得到状态
protected:
STATE m_nSubjectState; // 模拟保存Subject状态的变量
std::list<Observer*> m_ListObserver; // 保存Observer指针的链表
};
// Observer抽象基类
class Observer
{
public:
Observer() : m_nObserverState(-1){}
virtual ~Observer(){}
// 纯虚函数,各个派生类可能有不同的实现
// 通知Observer状态发生了变化
virtual void Update(Subject* pSubject) = 0;
protected:
STATE m_nObserverState; // 模拟保存Observer状态的变量
};
// ConcreateSubject类,派生在Subject类
class ConcreateSubject
PDF created with pdfFactory trial version www.pdffactory.com
: public Subject
{
public:
ConcreateSubject() : Subject(){}
virtual ~ConcreateSubject(){}
// 派生类自己实现来覆盖基类的实现
virtual void SetState(STATE nState); // 设置状态
virtual STATE GetState(); // 得到状态
};
// ConcreateObserver类派生自Observer
class ConcreateObserver
: public Observer
{
public:
ConcreateObserver() : Observer(){}
virtual ~ConcreateObserver(){}
// 虚函数,实现基类提供的接口
virtual void Update(Subject* pSubject);
};
#endif
2)Observer.cpp
/**************************************************************
******
created: 2006/07/20
filename: Observer.cpp
author: 李创
http://www.cppblog.com/converse/
purpose: Observer模式的演示代码
****************************************************************
*****/
#include "Observer.h"
#include <iostream>
#include <algorithm>
/* --------------------------------------------------------------------
PDF created with pdfFactory trial version www.pdffactory.com
| Subject 类成员函数的实现
|
----------------------------------------------------------------------*/
void Subject::Attach(Observer *pObserver)
{
std::cout << "Attach an Observer\n";
m_ListObserver.push_back(pObserver);
}
void Subject::Detach(Observer *pObserver)
{
std::list<Observer*>::iterator iter;
iter = std::find(m_ListObserver.begin(), m_ListObserver.end(), pObserver);
if (m_ListObserver.end() != iter)
{
m_ListObserver.erase(iter);
}
std::cout << "Detach an Observer\n";
}
void Subject::Notify()
{
std::cout << "Notify Observers's State\n";
std::list<Observer*>::iterator iter1, iter2;
for (iter1 = m_ListObserver.begin(), iter2 = m_ListObserver.end();
iter1 != iter2;
++iter1)
{
(*iter1)->Update(this);
}
}
void Subject::SetState(STATE nState)
{
std::cout << "SetState By Subject\n";
m_nSubjectState = nState;
}
PDF created with pdfFactory trial version www.pdffactory.com
STATE Subject::GetState()
{
std::cout << "GetState By Subject\n";
return m_nSubjectState;
}
Subject::~Subject()
{
std::list<Observer*>::iterator iter1, iter2, temp;
for (iter1 = m_ListObserver.begin(), iter2 = m_ListObserver.end();
iter1 != iter2;
)
{
temp = iter1;
++iter1;
delete (*temp);
}
m_ListObserver.clear();
}
/* --------------------------------------------------------------------
| ConcreateSubject类成员函数的实现
|
----------------------------------------------------------------------*/
void ConcreateSubject::SetState(STATE nState)
{
std::cout << "SetState By ConcreateSubject\n";
m_nSubjectState = nState;
}
STATE ConcreateSubject::GetState()
{
std::cout << "GetState By ConcreateSubject\n";
return m_nSubjectState;
}
/* --------------------------------------------------------------------
| ConcreateObserver类成员函数的实现
|
----------------------------------------------------------------------*/
void ConcreateObserver::Update(Subject* pSubject)
{
PDF created with pdfFactory trial version www.pdffactory.com
if (NULL == pSubject)
return;
m_nObserverState = pSubject->GetState();
std::cout << "The ObeserverState is " << m_nObserverState << std::endl;
}
3)Main.cpp
/**************************************************************
******
created: 2006/07/21
filename: Main.cpp
author: 李创
http://www.cppblog.com/converse/
purpose: Observer模式的测试代码
****************************************************************
*****/
#include "Observer.h"
#include <iostream>
int main()
{
Observer *p1 = new ConcreateObserver;
Observer *p2 = new ConcreateObserver;
Subject* p = new ConcreateSubject;
p->Attach(p1);
p->Attach(p2);
p->SetState(4);
p->Notify();
p->Detach(p1);
p->SetState(10);
p->Notify();
delete p;
system("pause");
return 0;
PDF created with pdfFactory trial version www.pdffactory.com
}
常见设计模式的解析和实现(C++)之十六-Strategy模

作用:
定义一系列的算法,把它们一个个封装起来, 并且使它们可相互替换.本模式使得
算法可独立于使用它的客户而变化.
UML结构图:
解析:
简而言之一句话,Strategy模式是对算法的封装.处理一个问题的时候可能有多
种算法,这些算法的接口(输入参数,输出参数等)都是一致的,那么可以考虑采用
Strategy模式对这些算法进行封装,在基类中定义一个函数接口就可以了.
实现:
1)Strategy.h
/**************************************************************
******
created: 2006/08/06
filename: Strategy.h
author: 李创
http://www.cppblog.com/converse/
purpose: Strategy模式的演示代码
****************************************************************
*****/
#ifndef STRATEGY_H
PDF created with pdfFactory trial version www.pdffactory.com
#define STRATEGY_H
class Strategy;
class Context
{
public:
Context(Strategy *pStrategy);
~Context();
void ContextInterface();
private:
Strategy* m_pStrategy;
};
class Strategy
{
public:
virtual ~Strategy(){}
virtual void AlgorithmInterface() = 0;
};
class ConcreateStrategyA
: public Strategy
{
public:
virtual ~ConcreateStrategyA(){}
virtual void AlgorithmInterface();
};
#endif
2)Strategy.cpp
/**************************************************************
******
created: 2006/08/06
filename: Strategy.cpp
author: 李创
http://www.cppblog.com/converse/
purpose: Strategy模式的演示代码
PDF created with pdfFactory trial version www.pdffactory.com
****************************************************************
*****/
#include <iostream>
#include "Strategy.h"
Context::Context(Strategy *pStrategy)
: m_pStrategy(pStrategy)
{
}
Context::~Context()
{
delete m_pStrategy;
m_pStrategy = NULL;
}
void Context::ContextInterface()
{
if (NULL != m_pStrategy)
{
m_pStrategy->AlgorithmInterface();
}
}
void ConcreateStrategyA::AlgorithmInterface()
{
std::cout << "AlgorithmInterface Implemented by ConcreateStrategyA\n";
}
3)Main.cpp
/**************************************************************
******
created: 2006/08/06
filename: Main.cpp
author: 李创
http://www.cppblog.com/converse/
purpose: Strategy模式的测试代码
****************************************************************
*****/
#include "Strategy.h"
PDF created with pdfFactory trial version www.pdffactory.com
int main()
{
Strategy* pStrategy = new ConcreateStrategyA();
Context* pContext = new Context(pStrategy);
pContext->ContextInterface();
delete pContext;
return 0;
}
常见设计模式的解析和实现(C++)之十七-State模式
作用:
允许一个对象在其内部状态改变时改变它的行为.
UML结构图:
解析:
State模式主要解决的是在开发中时常遇到的根据不同的状态需要进行不同的
处理操作的问题,而这样的问题,大部分人是采用switch-case语句进行处理的,
这样会造成一个问题:分支过多,而且如果加入一个新的状态就需要对原来的代
码进行编译.State模式采用了对这些不同的状态进行封装的方式处理这类问题,
当状态改变的时候进行处理然后再切换到另一种状态,也就是说把状态的切换责
任交给了具体的状态类去负责.同时,State模式和Strategy模式在图示上有很
多相似的地方,需要说明的是两者的思想都是一致的,只不过封装的东西不同:St
ate模式封装的是不同的状态,而Stategy模式封装的是不同的算法.
PDF created with pdfFactory trial version www.pdffactory.com
实现:
1)State.h
/**************************************************************
******
created: 2006/08/05
filename: State.h
author: 李创
http://www.cppblog.com/converse/
purpose: State模式的演示代码
****************************************************************
*****/
#ifndef STATE_H
#define STATE_H
class State;
class Context
{
public:
Context(State* pState);
~Context();
void Request();
void ChangeState(State *pState);
private:
State *m_pState;
};
class State
{
public:
virtual ~State(){}
virtual void Handle(Context* pContext) = 0;
};
class ConcreateStateA
: public State
{
public:
void Handle(Context* pContext);
};
PDF created with pdfFactory trial version www.pdffactory.com
class ConcreateStateB
: public State
{
public:
void Handle(Context* pContext);
};
#endif
2)State.cpp
/**************************************************************
******
created: 2006/08/05
filename: State.cpp
author: 李创
http://www.cppblog.com/converse/
purpose: State模式的演示代码
****************************************************************
*****/
#include "State.h"
#include <iostream>
Context::Context(State* pState)
: m_pState(pState)
{
}
Context::~Context()
{
delete m_pState;
m_pState = NULL;
}
void Context::Request()
{
if (NULL != m_pState)
{
m_pState->Handle(this);
}
PDF created with pdfFactory trial version www.pdffactory.com
}
void Context::ChangeState(State *pState)
{
if (NULL != m_pState)
{
delete m_pState;
m_pState = NULL;
}
m_pState = pState;
}
void ConcreateStateA::Handle(Context* pContext)
{
std::cout << "Handle by ConcreateStateA\n";
if (NULL != pContext)
{
pContext->ChangeState(new ConcreateStateB());
}
}
void ConcreateStateB::Handle(Context* pContext)
{
std::cout << "Handle by ConcreateStateB\n";
if (NULL != pContext)
{
pContext->ChangeState(new ConcreateStateA());
}
}
3)Main.cpp
/**************************************************************
******
created: 2006/08/05
filename: Main.cpp
author: 李创
http://www.cppblog.com/converse/
purpose: State模式的测试代码
****************************************************************
PDF created with pdfFactory trial version www.pdffactory.com
*****/
#include "State.h"
int main()
{
State *pState = new ConcreateStateA();
Context *pContext = new Context(pState);
pContext->Request();
pContext->Request();
pContext->Request();
delete pContext;
return 0;
}
常见设计模式的解析和实现(C++)之十八-Iterator模

作用:
提供一种方法顺序访问一个聚合对象中各个元素,,而又不需暴露该对象的内部
表示.
UML结构图:
解析:
PDF created with pdfFactory trial version www.pdffactory.com
Iterator几乎是大部分人在初学C++的时候就无意之中接触到的第一种设计模
式,因为在STL之中,所有的容器类都有与之相关的迭代器.以前初学STL的时候,
时常在看到讲述迭代器作用的时候是这么说的:提供一种方式,使得算法和容器
可以独立的变化,而且在访问容器对象的时候不必暴露容器的内部细节,具体是
怎么做到这一点的呢?在STL的实现中,所有的迭代器(Iterator)都必须遵照一
套规范,这套规范里面定义了几种类型的名称,比如对象的名称,指向对象的指针
的名称,指向对象的引用的名称....等等,当新生成一个容器的时候与之对应的It
erator都要遵守这个规范里面所定义的名称,这样在外部看来虽然里面的实现细
节不一样,但是作用(也就是对外的表象)都是一样的,通过某个名称可以得到容
器包含的对象,通过某个名称可以得到容器包含的对象的指针等等的.而且,采用
这个模式把访问容器的重任都交给了具体的iterator类中.于是,在使用Iterato
r来访问容器对象的算法不需要知道需要处理的是什么容器,只需要遵守事先约
定好的Iterator的规范就可以了;而对于各个容器类而言,不管内部的事先如何,
是树还是链表还是数组,只需要对外的接口也遵守Iterator的标准,这样算法(It
erator的使用者)和容器(Iterator的提供者)就能很好的进行合作,而且不必关
心对方是如何事先的,简而言之,Iterator就是算法和容器之间的一座桥梁.
在下面的实现中,抽象基类Iterator可以看做是前面提到的Iterator的规范,它
提供了所有Iterator需要遵守的规范也就是对外的接口,而它的派生类Concre
ateIterator则是ConcreateAggregate容器的迭代器,它遵照这个规范对容器
进行迭代和访问操作.
实现:
1)Iterator.h
/**************************************************************
******
created: 2006/08/04
filename: Iterator.h
author: 李创
http://www.cppblog.com/converse/
purpose: Iterator模式的演示代码
****************************************************************
*****/
#ifndef ITERATOR_H
#define ITERATOR_H
typedef int DATA;
class Iterater;
// 容器的抽象基类
class Aggregate
PDF created with pdfFactory trial version www.pdffactory.com
{
public:
virtual ~Aggregate(){}
virtual Iterater* CreateIterater(Aggregate *pAggregate) = 0;
virtual int GetSize() = 0;
virtual DATA GetItem(int nIndex) = 0;
};
// 迭代器的抽象基类
class Iterater
{
public:
virtual ~Iterater(){}
virtual void First() = 0;
virtual void Next() = 0;
virtual bool IsDone() = 0;
virtual DATA CurrentItem() = 0;
private:
};
// 一个具体的容器类,这里是用数组表示
class ConcreateAggregate
: public Aggregate
{
public:
ConcreateAggregate(int nSize);
virtual ~ConcreateAggregate();
virtual Iterater* CreateIterater(Aggregate *pAggregate);
virtual int GetSize();
virtual DATA GetItem(int nIndex);
private:
int m_nSize;
DATA *m_pData;
};
// 访问ConcreateAggregate容器类的迭代器类
class ConcreateIterater
: public Iterater
{
PDF created with pdfFactory trial version www.pdffactory.com
public:
ConcreateIterater(Aggregate* pAggregate);
virtual ~ConcreateIterater(){}
virtual void First();
virtual void Next();
virtual bool IsDone();
virtual DATA CurrentItem();
private:
Aggregate *m_pConcreateAggregate;
int m_nIndex;
};
#endif
2)Iterator.cpp
/**************************************************************
******
created: 2006/08/04
filename: Iterator.cpp
author: 李创
http://www.cppblog.com/converse/
purpose: Iterator模式的演示代码
****************************************************************
*****/
#include <iostream>
#include "Iterator.h"
ConcreateAggregate::ConcreateAggregate(int nSize)
: m_nSize(nSize)
, m_pData(NULL)
{
m_pData = new DATA[m_nSize];
for (int i = 0; i < nSize; ++i)
{
m_pData[i] = i;
}
}
PDF created with pdfFactory trial version www.pdffactory.com
ConcreateAggregate::~ConcreateAggregate()
{
delete [] m_pData;
m_pData = NULL;
}
Iterater* ConcreateAggregate::CreateIterater(Aggregate *pAggregate)
{
return new ConcreateIterater(this);
}
int ConcreateAggregate::GetSize()
{
return m_nSize;
}
DATA ConcreateAggregate::GetItem(int nIndex)
{
if (nIndex < m_nSize)
{
return m_pData[nIndex];
}
else
{
return -1;
}
}
ConcreateIterater::ConcreateIterater(Aggregate* pAggregate)
: m_pConcreateAggregate(pAggregate)
, m_nIndex(0)
{
}
void ConcreateIterater::First()
{
m_nIndex = 0;
}
void ConcreateIterater::Next()
{
if (m_nIndex < m_pConcreateAggregate->GetSize())
{
PDF created with pdfFactory trial version www.pdffactory.com
++m_nIndex;
}
}
bool ConcreateIterater::IsDone()
{
return m_nIndex == m_pConcreateAggregate->GetSize();
}
DATA ConcreateIterater::CurrentItem()
{
return m_pConcreateAggregate->GetItem(m_nIndex);
}
3_Main.cpp
/**************************************************************
******
created: 2006/08/08
filename: Main.cpp
author: 李创
http://www.cppblog.com/converse/
purpose: Iterater模式的演示代码
****************************************************************
*****/
#include "Iterator.h"
#include <iostream>
int main()
{
Aggregate* pAggregate = new ConcreateAggregate(4);
Iterater* pIterater = new ConcreateIterater(pAggregate);
for (; false == pIterater->IsDone(); pIterater->Next())
{
std::cout << pIterater->CurrentItem() << std::endl;
}
return 0;
}
PDF created with pdfFactory trial version www.pdffactory.com
常见设计模式的解析和实现(C++)之十九-Memento
模式
作用:
在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个
状态.这样以后就可将该对象恢复到原先保存的状态.
UML结构图:
解析:
Memento模式中封装的是需要保存的状态,当需要恢复的时候才取出来进行恢
复.原理很简单,实现的时候需要注意一个地方:窄接口和宽接口.所谓的宽接口就
是一般意义上的接口,把对外的接口作为public成员;而窄接口反之,把接口作为
private成员,而把需要访问这些接口函数的类作为这个类的友元类,也就是说接
口只暴露给了对这些接口感兴趣的类,而不是暴露在外部.下面的实现就是窄实
现的方法来实现的.
实现:
1)Memento.h
/**************************************************************
******
created: 2006/08/09
filename: Memento.h
author: 李创
http://www.cppblog.com/converse/
purpose: Memento模式的演示代码
****************************************************************
*****/
#ifndef MEMENTO_H
PDF created with pdfFactory trial version www.pdffactory.com
#define MEMENTO_H
#include <string>
typedef std::string State;
class Memento;
class Originator
{
public:
Originator(const State& rState);
Originator();
~Originator();
Memento* CreateMemento();
void SetMemento(Memento* pMemento);
State GetState();
void SetState(const State& rState);
void RestoreState(Memento* pMemento);
void PrintState();
private:
State m_State;
};
// 把Memento的接口函数都设置为私有的,而Originator是它的友元,
// 这样保证了只有Originator可以对其访问
class Memento
{
private:
friend class Originator;
Memento(const State& rState);
void SetState(const State& rState);
State GetState();
State m_State;
};
#endif
2)Memento.cpp
PDF created with pdfFactory trial version www.pdffactory.com
/**************************************************************
******
created: 2006/08/09
filename: Memento.cpp
author: 李创
http://www.cppblog.com/converse/
purpose: Memento模式的演示代码
****************************************************************
*****/
#include "Memento.h"
#include <iostream>
Originator::Originator()
{
}
Originator::Originator(const State& rState)
: m_State(rState)
{
}
Originator::~Originator()
{
}
State Originator::GetState()
{
return m_State;
}
void Originator::SetState(const State& rState)
{
m_State = rState;
}
Memento* Originator::CreateMemento()
{
return new Memento(m_State);
}
PDF created with pdfFactory trial version www.pdffactory.com
void Originator::RestoreState(Memento* pMemento)
{
if (NULL != pMemento)
{
m_State = pMemento->GetState();
}
}
void Originator::PrintState()
{
std::cout << "State = " << m_State << std::endl;
}
Memento::Memento(const State& rState)
: m_State(rState)
{
}
State Memento::GetState()
{
return m_State;
}
void Memento::SetState(const State& rState)
{
m_State = rState;
}
3)Main.cpp
/**************************************************************
******
created: 2006/08/09
filename: Main.cpp
author: 李创
http://www.cppblog.com/converse/
purpose: Memento模式的测试代码
****************************************************************
*****/
#include "Memento.h"
PDF created with pdfFactory trial version www.pdffactory.com
int main()
{
// 创建一个原发器
Originator* pOriginator = new Originator("old state");
pOriginator->PrintState();
// 创建一个备忘录存放这个原发器的状态
Memento *pMemento = pOriginator->CreateMemento();
// 更改原发器的状态
pOriginator->SetState("new state");
pOriginator->PrintState();
// 通过备忘录把原发器的状态还原到之前的状态
pOriginator->RestoreState(pMemento);
pOriginator->PrintState();
delete pOriginator;
delete pMemento;
return 0;
}
常见设计模式的解析和实现(C++)之二十-Visitor模式
作用:
表示一个作用于某对象结构中的各元素的操作.它使你可以在不改变各元素的类
的前提下定义作用于这些元素的新操作.
UML结构图:
PDF created with pdfFactory trial version www.pdffactory.com
解析:
Visitor模式把对结点的访问封装成一个抽象基类,通过派生出不同的类生成新
的访问方式.在实现的时候,在visitor抽象基类中声明了对所有不同结点进行访
问的接口函数,如图中的VisitConcreateElementA函数等,这样也造成了Visit
or模式的一个缺陷--新加入一个结点的时候都要添加Visitor中的对其进行访问
接口函数,这样使得所有的Visitor及其派生类都要重新编译了,也就是说Visitor
模式一个缺点就是添加新的结点十分困难.另外,还需要指出的是Visitor模式采
用了所谓的"双重分派"的技术,拿上图来作为例子,要对某一个结点进行访问,首
先需要产生一个Element的派生类对象,其次要传入一个Visitor类派生类对象
来调用对应的Accept函数,也就是说,到底对哪种Element采用哪种Visitor访
问,需要两次动态绑定才可以确定下来,具体的实现可以参考下面实现代码中的
Main.cpp部分是如何调用这些类的.
实现:
1)Visitor.h
/**************************************************************
******
created: 2006/08/09
filename: Visitor.h
PDF created with pdfFactory trial version www.pdffactory.com
author: 李创
http://www.cppblog.com/converse/
purpose: Visitor模式的演示代码
****************************************************************
*****/
#ifndef VISITOR_H
#define VISITOR_H
class Visitor;
class Element
{
public:
virtual ~Element(){}
virtual void Accept(Visitor &rVisitor) = 0;
protected:
Element(){}
};
class ConcreateElementA
: public Element
{
public:
virtual ~ConcreateElementA() {}
virtual void Accept(Visitor &rVisitor);
};
class ConcreateElementB
: public Element
{
public:
virtual ~ConcreateElementB() {}
virtual void Accept(Visitor &rVisitor);
};
class Visitor
{
public:
PDF created with pdfFactory trial version www.pdffactory.com
virtual ~Visitor(){}
virtual void VisitConcreateElementA(ConcreateElementA *pConcreateElement
A) = 0;
virtual void VisitConcreateElementB(ConcreateElementB *pConcreateElement
B) = 0;
protected:
Visitor(){}
};
class ConcreateVisitorA
: public Visitor
{
public:
virtual ~ConcreateVisitorA(){}
virtual void VisitConcreateElementA(ConcreateElementA *pConcreateElement
A);
virtual void VisitConcreateElementB(ConcreateElementB *pConcreateElement
B);
};
class ConcreateVisitorB
: public Visitor
{
public:
virtual ~ConcreateVisitorB(){}
virtual void VisitConcreateElementA(ConcreateElementA *pConcreateElement
A);
virtual void VisitConcreateElementB(ConcreateElementB *pConcreateElement
B);
};
#endif
2)Visitor.cpp
/**************************************************************
******
created: 2006/08/09
filename: Visitor.cpp
author: 李创
PDF created with pdfFactory trial version www.pdffactory.com
http://www.cppblog.com/converse/
purpose: Visitor模式的演示代码
****************************************************************
*****/
#include "Visitor.h"
#include <iostream>
void ConcreateElementA::Accept(Visitor &rVisitor)
{
rVisitor.VisitConcreateElementA(this);
}
void ConcreateElementB::Accept(Visitor &rVisitor)
{
rVisitor.VisitConcreateElementB(this);
}
void ConcreateVisitorA::VisitConcreateElementA(ConcreateElementA *pConcreat
eElementA)
{
std::cout << "VisitConcreateElementA By ConcreateVisitorA\n";
}
void ConcreateVisitorA::VisitConcreateElementB(ConcreateElementB *pConcreat
eElementA)
{
std::cout << "VisitConcreateElementB By ConcreateVisitorA\n";
}
void ConcreateVisitorB::VisitConcreateElementA(ConcreateElementA *pConcreat
eElementA)
{
std::cout << "VisitConcreateElementA By ConcreateVisitorB\n";
}
void ConcreateVisitorB::VisitConcreateElementB(ConcreateElementB *pConcreat
eElementA)
{
std::cout << "VisitConcreateElementB By ConcreateVisitorB\n";
}
PDF created with pdfFactory trial version www.pdffactory.com
3)Main.cpp
/**************************************************************
******
created: 2006/08/09
filename: Main.cpp
author: 李创
http://www.cppblog.com/converse/
purpose: Visitor模式的测试代码
****************************************************************
*****/
#include "Visitor.h"
int main()
{
Visitor *pVisitorA = new ConcreateVisitorA();
Element *pElement = new ConcreateElementA();
pElement->Accept(*pVisitorA);
delete pElement;
delete pVisitorA;
return 0;
}
常见设计模式的解析和实现(C++)之二十一-完结篇
一个月下来,把常见的20个设计模式好好复习并且逐个用C++实现了一
遍,收获还是很大的,很多东西看上去明白了但是真正动手去做的时候发现其实
还是不明白--我深知这个道理,于是不敢怠慢,不敢写什么所谓的解释原理的伪
代码,不敢说所谓的"知道原理就可以了"....因为我知道,我还还没有资格说这个
话,至少对于设计模式而言我还是一个初学者,唯有踏实和实干才能慢慢的掌握
到知识.
在我学习设计模式的过程中,觉得造成理解困难的主要是以下几点,谈一
下自己的体会,希望对他人有帮助,不要走上我的老路上,毕竟我花了N长的时间
才敢号称自己入门了~~!!-_-:
1)Gof并不适合于初学者.初学设计模式的一般都是从Gof入门开始学习
PDF created with pdfFactory trial version www.pdffactory.com
的,不幸的是,这不是一本好的教科书,而把这本书称为一本奠定了设计模式理论
基础的开山之作也许好一些,它把这些散落在各个设计中的常见模式收集起来,
从此开始有了一个名词叫做"Design Pattern".说这本书不是一本好的教科书
主要是以下的几个原因:a)对设计模式或者说面向对象里面的一些原则性的东西
解释的不够多不够彻底,比如"面向接口编程而不是对实现编程","优先采用组合
而不是继承"等等,以至于后面看到各个模式的实现的时候很多模式看起来很相
似却找不到区别和共性的地方. b)对各个模式的解释或者举出来的例子不是特
别的好,大部分都是为了讲解模式而讲解,没有加入前面提到过的一些基本原则
的考量在里面,也就是说:原理性的东西和实现(各个设计模式)脱节.
2)初学者对语言或者说一些概念理解的不好.拿C++来说,为了做到面向
对象需要提供的语言上的支持有继承,多态,封装,虚函数,抽象等等,我以前初学
C++的时候,只为了学这些概念而去学习,不知道为什么要提供这些特性,这也是
造成我走弯路的重要原因之一.当然,指望一个初学者在初学语言的时候就知道
why是一件很困难的事情,也许结合着对设计模式的理解可以帮助你消化这些概
念(我就是这样的).
3)看不懂UML结构图和时序图,UML图解释的类与类之间的关系,时序图
解释的是各个对象的实现方式,两者结合在一起看才能加深对设计模式的理解,
事实上,我现在已经可以做到仅仅看这两个图示就掌握一个模式的原理和实现了.
4)写的代码和参与过的项目不够多.设计模式和很多东西的产生过程都是
一样的,首先人们遇到了问题,然后很多人解决了这个问题,于是渐渐的有人出来
总结出解决这些问题所要遵守的一些原理和常用方法(我们称之为"模式"),久而
久之就形成了一个理论或者说一个学科.而后人在讲述这些理论的时候大都是照
本宣科,这对于计算机这样一个强调实践的学科或者说对于设计模式这样一个理
论而言要理解起来是很困难的.前人在提出这些理论的时候一些考量,权衡等等
只有在你自己遇到了这些问题的时候才能慢慢的体会.有一种说法是,没有写上1
0W行代码不要空谈什么设计模式大概就是这个意思吧.
综上所述,造成初学者学习设计模式困难的原因,一个是对基本的原则理
解的不够透彻,一个的选的入门教材不合理,还有一个就是对各个模式的表述不
明白,再次是实践不够多.
有几本书籍,我看过,我想可以谈谈我的看法.
第一本,<<敏捷软件开发:原则,模式与实践>>,这本书对于设计模式最
大的贡献在于专门有几个章节讲述了面向对象的几个原则,比如Likov原则,开放
封闭原则等等的,这几个章节在我学习设计模式的过程中起了关键的作用,因为
当我理解了这些原则之后开始慢慢明白为什么要有纯虚函数提供接口,为什么要
有抽象基类,为什么要封装....我开始用这些原则去理解各个设计模式,开始慢慢
体会各个模式的区别和共性.
另外看过的两本书,我觉得性质都一样,如果你缺钱,任选其一吧.第一本是
<<设计模式精解>>,第二本是<<深入浅出设计模式>>,都是我花上几个晚上
PDF created with pdfFactory trial version www.pdffactory.com
就可以看完的书.这两本的立足点都是以生动的例子结合面向对象的基本原理来
讲解模式,我更喜欢前者一些(后者太贵,要不是打5折我才不买呐:)
其次,要多接触项目或者可以找一些好的代码来看看,自己也多写一些代码.
基本上,只要是用面向对象的语言开发的项目,里面没有几个模式的运用是不可
能的了.因此,要戒除那些一开始接触设计模式就想整明白的幻想,因为要真正的
理解需要很多的实践,同样的一时半会理解不了的也不必气馁(GOF的E文版我
看了好多遍了:),坚信自己多实践一定可以慢慢的悟道的.
关于设计模式的一个疑问:非面向对象语言中有没有所谓的"设计模式"?设
计模式最初的定义是解决一些问题的惯用方法(大意如此),并没有明确的说必须
要支持某种特性的语言.我用纯C开发的项目实在是有限,平时也只是自己作一
些小东西玩玩,没有做过任何一个上万行的纯C开发的项目,所以一直对这个问
题抱有疑问~~anyway,有问题是好事,说明我在思考~~把这个问题放在这里,
以后慢慢实践之琢磨之~~
博君一笑.
关于设计模式,还有一篇有意思的文章--<<追MM与设计模式>>,这篇文
章可谓是"寓教于乐"的典范,讲述了23个模式在日常生活中的原型,虽然没有具
体讲述如何实现,但是对于理解各个设计模式的运用场合还是很有帮助的.相信
对设计模式已经有了一定了解的人看了这篇文章都会会心一笑:),作者和出处已
经不详了.
PDF created with pdfFactory trial version www.pdffactory.com
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: