1 创建型模式(5)
Factory (工厂方法,最常用)
AbstactFactory (抽象工厂,与工厂方法一道组成"工厂模式")
Singleton
Builder
Prototype
1,factory method(工厂方法)
问题:
I,多态中,A为基类,B为派生类,用A*指向一个new B产生的对象,实现多态,当有多个A的派生类时,要多次使用new ***,这就要求使用并记住多个子类名,可能引起名字冲突;
II,A为抽象基类,B为A的派生类,C不是A的派生类而是创建者类,D是C的派生类: 如果C中要使用A,且A有多个派生类,C中并不知道A的哪个派生类将被实例化,但是在D中可以知道A的哪个派生类会被实例化.
由此引出了Factory模式的两个最重要的功能:
1)定义创建对象的接口,封装了对象的创建,特别适用于创建工作比较复杂的情况;
2)使得具体化类的工作延迟到了子类中。
总结: 模式的功能与适用情况不是一成不变的,但一般要专门实现一个类来作为Factory以生产类**的对象, 先声明类**,再用类***来生成**的指针对象,这就是工厂方法.
代码:
class basecls
{
public:
basecls() {}
virtual ~basecls() {}
};
class subclsA:public basecls
{
public:
subclsA(char *name) { cout<<name<<endl; }
virtual ~subclsA() {}
};
class subclsB: public basecls
{
public:
subclsB(char *name) { cout<<name<<endl; }
virtual ~subclsB() {}
};
class creator
{
public:
creator() {}
virtual ~creator() {}
basecls* createobj( char name)
{
switch(name)
{
case 'A':
return (new subclsA("sub class A"));
case 'B':
return (new subclsB("sub class B"));
}
}
};
int _tmain(int argc, _TCHAR* argv[])
{
basecls*pobj=(new creator)->createobj('A');
DELETEIF(pobj);
pobj=(new creator)->createobj('B');
DELETEIF(pobj);
return 0;
}
点评:在上面的代码中,如果在用 class subcreator: public creator 然后在subcreator中实现对subclsA和subclsB的创建,则是Factory method 的第二种功能体现: 延迟对象创建.
FactoryMethod模式仅仅局限于具有共同基类的类的创建,这一点,由creator的createobj方法返回basecls决定了; 如果我们要为不同类的类提供一个对象创建的接口,那就要用抽象工厂AbstractFactory.
2,abstractfactory
问题: FactoryMethod模式仅仅局限于具有共同基类的类的创建,我们可能要为不同类的类提供一个对象创建的接口.
class ProductA //假设这是怪物AbsProductA类
{
public:
ProductA(){ cout<<"This is ProductA----"; }
};
class ProductA_10:public ProductA //这是等级为10的AbsProductA类怪物
{
public:
ProductA_10(){ cout<<"ProductA_10::leavl= 10/n"; }
};
class ProductA_20:public ProductA //这是等级为20的AbsProductA类怪物
{
public:
ProductA_20(){ cout<<"ProductA_20::leavl= 20/n"; }
};
class ProductB //假设这是怪物AbsProductB类
{
public:
ProductB(){ cout<<"This is ProductB----"; }
};
class ProductB_10:public ProductB //这是等级为10的AbsProductB类怪物
{
public:
ProductB_10(){ cout<<"ProductB_10::leavl= 10/n"; }
};
class ProductB_20:public ProductB //这是等级为20的AbsProductB类怪物
{
public:
ProductB_20(){ cout<<"ProductB_20::leavl= 20/n"; }
};
class AbsFactory //怪物生产机
{
public:
virtual ProductA*CreateProductA()=0;
virtual ProductB*CreateProductB()=0;
};
class FactoryLeavl10:public AbsFactory//专门生产等级为10的怪物
{
public:
ProductA*CreateProductA(){ return new ProductA_10; }
ProductB*CreateProductB(){ return new ProductB_10; }
};
class FactoryLeavl20:public AbsFactory //专门生产等级为20的怪物
{
public:
ProductA*CreateProductA(){ return new ProductA_20; }
ProductB*CreateProductB(){ return new ProductB_20; }
};
int main()
{
AbsFactory* pFacA=new FactoryLeavl10;
pFacA->CreateProductA(); //生产等级为10的A类怪物
pFacA->CreateProductB(); //生产等级为10的B类怪物
AbsFactory* pFacB=new FactoryLeavl20;
pFacB->CreateProductA(); //生产等级为20的A类怪物
pFacB->CreateProductB(); //生产等级为20的B类怪物
return 0;
}
3,SingleTon(单态)模式是最简单的一种设计模式,它用于保证一个类只有一个实例存在.道理也很简单,用的是自身类型的static指针和一个返回该指针的static函数:
#include <iostream>
using namespace std;
class singleton
{
public:
singleton() { cout<<"construct a singleton object/n"; }
~singleton(){ if(_instance) { delete _instance; _instance=0; } }
static singleton*getinstance();
private:
static singleton* _instance;
};
singleton* singleton::_instance=0;
singleton* singleton::getinstance()
{
if (!_instance)
{
_instance=new singleton;
}
return _instance;
}
int main()
{
singleton*pobj=singleton::getinstance();
singleton*pobj2=singleton::getinstance();
return 0;
}
4,Builder (创建者)
问题提出: 有时要创建的一个对象是很复杂的,它由很多其他类型的对象组成,这时可一步步地创建该复杂对象,在每一步都传入参数,产生一个与前一步不同的对象. 这就是Builder的任务. 比如,一辆汽车是一个对象,它由四个车轮,四个车窗,车身,方向盘等组成. 我们先造车身,再安车窗,再装车轮等等.
这是一个将对象表示与创建分离的模式,product为整体,PartX为部分,它们都是表示部分,且整体与部分之间无继承关系, Builder为创建者,往往作为基类,定义一些虚函数, CoCreateBuilder为Builder的实现者类,创建各个PartX. 另外还有一个Director,这是由用户使用的,它有一个以Builder为参数的函数Construct,客户只要传递一个CoCreateBuilder对象给Construct,就可以完成对象的创建,而不必知道创建复杂对象的具体过程.
#include <iostream>
using namespace std;
class PartA;
class PartB;
class Product //整体
{
public:
Product(PartA*Pa=0, PartB*Pb=0) //部分构成整体
{
if(Pa!=0&&Pb!=0)
{
memberA=Pa;
memberB=Pb;
cout<<"This is Product/n";
}
}
private:
PartA*memberA; //部分
PartB*memberB;
};
class PartA
{
public:
PartA(){ cout<<"This is PartA/n"; } //A部分
};
class PartB
{
public:
PartB(){ cout<<"This is PartB/n"; } //B部分
};
class Builder //创建者
{
public:
virtual PartA*CreatePartA()=0; //创建A部分
virtual PartB*CreatePartB()=0; //创建B部分
virtual PartA*GetPartA()=0; //取出A部分
virtual PartB*GetPartB()=0; //取出B部分
virtual Product*GetProduct()=0;
};
class CoCreateBuilder:public Builder //实现创建者
{
public:
PartA*CreatePartA(){ return (memberA=new PartA); }
PartB*CreatePartB(){ return (memberB=new PartB); }
PartA*GetPartA(){ return memberA; }
PartB*GetPartB(){ return memberB; }
Product*GetProduct(){ return new Product(memberA,memberB); }//将部分组合成整体
private:
PartA*memberA;
PartB*memberB;
};
class Director //由用户程序员使用的二级创建者
{
public:
void CreatePart(Builder*pobj) //创建部分
{
pobj->CreatePartA();
pobj->CreatePartB();
}
Product* CreateProduct(Builder*pobj) //创建整体
{
this->CreatePart(pobj);
return pobj->GetProduct();
}
};
int main()
{
Director* pDirector=new Director;
pDirector->CreateProduct(new CoCreateBuilder); //真正创建复杂对象,这是很有意思的,有一个CoCreateBuilder对象
return 0; //作参数,调用Director的函数,竟然得到了想要Product.哈哈
}
理解Builder模式最重要在于理解复杂对象由部分对象构成, 而其创建者与对象本身是分离的. 至于为什么不用Builder直接实现CoCreateBuild
的功能,主要是考虑到代码的整洁, Builder专门负责提供接口, 而CoCreateBuilder将产生一个完整的复杂对象.
5,Prototype(原型模式)
原型模式就是通过已有实例来复制生成新的对象,克隆.
这是很简单的一种模式,就是用一个Clone函数调用重载的复制构造函数而已:
#include <iostream>
using namespace std;
class basecls //接口,提供clone方法
{
public:
basecls() {}
~basecls() {}
virtual basecls*clone()const=0;
};
class dervcls:public basecls
{
public:
dervcls() { cout<<"constructor/n"; }
dervcls(const dervcls&obj) { *this=obj; cout<<"overload copy constructor/n"; } //复制构造函数
~dervcls() {}
virtual basecls*clone()const { return new dervcls(*this); } //实现clone函数
};
int main()
{
basecls*pobj1=new dervcls;
basecls*pobj2=pobj1->clone(); //调用clone,克隆对象
basecls*pobj3=pobj2->clone(); //再次克隆
return 0;
}
以上就是五种GOF创建模式,都是针对对象的创建而提出的,FactoryMethod 封装对象创建,AbstracFactory用于创建多个有关联的对象,Singleton用于保持对象的唯一性,Builder 强调复杂对象的各个部分的逐步创建, Prototype主要利用已有对象创建其他对象.