0. Introduction
接触设计模式有两q时间了Q但一直没有系l整理过Qؓ了不至于让自q思维被繁琐的工作一点点锢Q还是决定ȝ一下,Z能够真正做到有所收获Q整个系列会按照GoF的Design Patterns: Elements of Reusable Object-Oriented Software的行文思\Q但不会照本宣科是了,Wikipedia上关?3U设计模式的介绍非常全面QCSDN上也可以下蝲?英文电子,因此很多套话、类图一概省厅R?/p>
最早接触设计模式的时候,隑օ被各U模式的联系和区别所困扰Q从教科书的分析可以得到模式之间形式上的不同。但q样对于领会设计模式意义不大Q因为我们掌握模式的目的是ؓ了融会诏通,灉|q用Q以对开发有所帮助?/p>
E微成规模的OOE序Q会有大量对象,其中很多实体对象之间存在着父子、兄?/strong>关系Q对象的创徏提升ZU模式。其好处在于设计模式本n所宣称?strong>reusableQ这像堆积木盖房子一P堆的好的情况下,换一换门H便是另一番风景?/p>
关于实现Q我不会Z厘清模式间的区别而刻意用相g码实玎ͼ相反Q我会根据模式本w的适用情况举例Q而且大量代码ZSourceMaking?/p>
_______________________________
1. Creational Design Patterns(DP)
创徏型DP抽象了类和对象的创徏q程Q?a title="Gang of four" target="_blank">GoFl出?U?strong>创徏型DPQ?strong>Abstract Factory?strong>Builder?strong>Factory Method?strong>Builder?strong>Prototype?strong>Singleton?/p>
2. Abstract Factory
意图Q提供一个创Zpd相关或相互依赖对象的接口Q而无需指定它们具体的类?/strong>
1) 只提供了一个创建接口,其返回gؓ具体产品Q如AbstractProduct *Client::CreateProduct(AbstractFactory &factory);
2) 接口的参数是一?strong>工厂对象Q?code>AbstractFactory &factoryQ的引用Q参数类型(AbstractFactory
Qؓ抽象基类Q调用时Ҏ需要传入具体工厂对象即可;
3) 接口内部实现?strong>一pd相关或相互依赖对?/strong>Q抽象品)的创建:当传入具体工厂时Q接口实现的是一pd具体产品的创建;
4) 创徏的?strong>立即q回Q?code>CreateProductQ?/p>
参与者:
• AbstractFactory
?声明一个创建抽象品对象的操作接口?/p>
• ConcreteFactory
?实现创徏具体产品对象的操作?/p>
• AbstractProduct
?ZcM品对象声明一个接口?/p>
• ConcreteProduct
?定义一个将被相应的具体工厂创徏的品对象?br>?实现AbstractProduct接口?/p>
• Client
?仅用由AbstractFactory和AbstractProductcd明的接口?/p>
代码Q?/strong>
class AbstractFactory
{
public:
virtual AbstractProduct *MakePartA() = 0;
virtual AbstractProduct *MakePartB() = 0;
virtual AbstractProduct *MakePartC() = 0;
virtual AbstractProduct *AddPart(const AbstractProduct *pPart) = 0;
};
AbstractProduct *Client::CreateProduct(AbstractFactory &factory)
{
AbstractProduct *pProduct = factory.CreateProduct();
AbstractProduct *pPartA = factory.MakePartA();
AbstractProduct *pPartB = factory.MakePartB();
AbstractProduct *pPartC = factory.MakePartC();
factory.AddPart(pPartA);
factory.AddPart(pPartB);
factory.AddPart(pPartC);
return pProduct;
}
int main(void)
{
Client client;
ConcreteFactory factory;
client.CreateProduct(factory);
return 0;
}
3. Builder
意图Q将一个复杂对象的构徏与它的表C分,使得同样的构E可以创Z同的表示?/strong>
1) director提供抽象产品创徏接口Q如void Director::Construct();
2) 不同产品使用同一创徏q程Q由director指定特定builder以生产不同品;
3) 接口内部实现?strong>一个复杂对?/strong>Q抽象品)的创建:当传入具体工厂时Q接口实现的?strong>一个复杂的具体产品的创建;
4) 创徏的?strong>q不立即q回Q?strong>创徏完毕后返回,?strong>使用接口Q?code>GetProductQ提取结果?/p>
参与者:
• Builder
?为创Z个Product对象的各个部件指定抽象接口?/p>
• ConcreteBuilder
?实现Builder的接口以构造和装配该品的各个部g?br>?定义q明它所创徏的表C?br>?提供一个检索品的接口?/p>
• Director
?构造一个用Builder接口的对象?/p>
• Product
?表示被构造的复杂对象。ConcreteBuilder创徏该品的内部表示q定义它的装配过E?br>?包含定义l成部g的类Q包括将q些部g装配成最l品的接口?/p>
代码Q?/strong>
class Builder
{
public:
virtual void MakePartA() = 0;
virtual void MakePartB() = 0;
virtual void MakePartC() = 0;
Product *GetProduct() { return _product; }
protected:
Product *_product;
};
class Director
{
public:
void setBuilder(Builder *b) { _builder = b; }
void Construct();
private:
Builder *_builder;
};
void Director::Construct()
{
_builder.MakePartA();
_builder.MakePartB();
_builder.MakePartC();
}
int main(void) {
ConcreteBuilderA concreteBuilderA;
ConcreteBuilderB concreteBuilderB;
Director director;
Product *pProduct;
director.SetBuilder(&concreteBuilderA);
director.Construct();
pProduct = concreteBuilderA.GetProduct();
pProduct->Show();
director.SetBuilder(&concreteBuilderB);
director.Construct();
pProduct = concreteBuilderB.GetProduct();
pProduct->Show();
return 0;
}
4. Factory Method
意图Q定义一个用于创建对象的接口Q让子类军_实例化哪一个类。Factory Method使一个类的实例化延迟到其子类?/strong>
1) 看得模式其实是C++的多态特?/strong>Q?strong>l承实现。因此,其别名ؓ虚构造器Q?Virtual ConstructorQ?/strong>Q?/p>
2) 作ؓ模式与C++多态特性不同的是,Creator可以定义工厂Ҏ的缺省实?/strong>Q完成缺省操作,MFC大量使用了这一思想?/p>
参与者: • Product • ConcreteProduct • Creator • ConcreteCreator 代码Q?/strong> int main(void) { pProduct = creator.FactoryMethod(); return 0; 5. Prototype 意图Q用原型实例指定创徏对象的种c,q且通过拯q些原型创徏新的对象?/strong> 1) 创徏不再通过工厂新类l承QinheritanceQ?/strong>Q而是通过委托QdelegationQ?/strong>Q?/p>
2) 栚w?strong>拯原型实例 参与者: • ProtoType • ConcreteProtoType • Client 代码Q?/strong> class ProtoType class ProtoTypeA: public ProtoType class ProtoTypeB: public ProtoType class Client private: ProtoType* Client::s_prototypes[] = { 0, new ProtoTypeA, new ProtoTypeB }; ProtoType *Client::Clone(int choice) 6. Singleton 意图Q保证一个类仅有一个实例,q提供一个访问它的全局讉K炏V?/strong> 1) ?strong>静态成员函?/strong>保证上述意图?/p>
参与者: • Singleton 代码Q?/strong> class Singleton void Run() {} private: Singleton *GetSingleton(void) int main(void) return 0; ______________________________________________ 代码写的都比较简单,基本可以各U模式之间的不同体现出来了?/p>
?定义工厂Ҏ所创徏的对象的接口?/p>
?实现Product接口?/p>
?声明工厂ҎQ该Ҏq回一个Productcd的对象。Creator也可以定义一个工厂方法的~省实现Q它q回一个缺省的ConcreteProduct对象?br>?可以调用工厂Ҏ以创Z个Product对象?/p>
?重定义工厂方法以q回一个ConcreteProduct实例?/p>
ConcreteProduct *ConcreteCreator::FactoryMethod()
{
ConcreteProduct
*pProduct = new ConcreteProduct
;
return pProduct;
}Product *Creator::FactoryMethod()
{
Product *pProduct = new Product;
return pProduct;
}
Creator creator;
ConcreteProduct *pProduct;
pProduct->Show();
}
?声明一个克隆自w的接口?/p>
?实现一个克隆自w的操作?/p>
?让一个原型克隆自w从而创Z个新的对象?/p>
{
public:
virtual void Draw();
virtual ProtoType *Clone() = 0;
virtual void Initialize();
};
{
public:
virtual ProtoType *Clone()
{
return new ProtoTypeA;
}
};
{
public:
virtual ProtoType *Clone()
{
return new ProtoTypeB;
}
};
{
public:
static ProtoType *Clone( int choice );
static ProtoType *s_prototypes[3];
};
{
return s_prototypes[choice]->Clone();
}
?定义一个Instance操作Q允许客戯问它的唯一实例。Instance是一个类操作Q即C++中的一个静态成员函敎ͼ?br>?可能负责创徏它自q唯一实例?/p>
{
public:
static Singleton *GetInstance()
{
if (!s_instance)
s_instance = new Singleton;
return s_instance;
}
static Singleton *s_instance;
Singleton() {} // Singleton cannot be created outside.
};
{
return Singleton::GetInstance();
}
{
GetSingleton()->Run();
}