[设计模式学习笔记二][创建型模式][工厂方法(Factory Method)]

来源:互联网 发布:微博刷阅读量软件 编辑:程序博客网 时间:2024/05/16 08:44
本文是我学习刘伟技术博客的笔记,博客链接如下:

http://blog.csdn.net/lovelion/article/details/17517213

我做的这部分笔记,鉴于自身水平有限,我只是对上面博客内做进一步提炼和记录,方便自己查阅。同时,更多的是对设计模式的框架进行学习,大部分细节都将略去,让自己侧重对每个设计模式框架的理解。

我应该理解和掌握的:

1)能够画出这个设计模式的架构框图;

2)能够根据架构框图写出对应的伪代码;

3)这个模式的应用场景,主要优缺点。

1.简单工厂

(1)定义

简单工厂不属于GoF 23个经典设计模式,这里为了引入工厂方法,抽象工厂做准备。

简单工厂模式定义:给定一个工厂类,它将根据传进来的不同参数返回不同类的实例,被创建的实例通常有共同的父类。简单工厂模式中用于创建实例的方法是静态方法,故又称静态工厂方法。

下面是结构图,具体代码将不再贴出,由框架自己在联想代码怎么设计以及每个类的作用:

结构图的伪代码如下:
enum ProductId{PRODUCTA,PRODUCTB,MAX,};class product //抽象产品类{public:virtual void display();};class ConcreteProductA:public product //具体产品类A{public:void display();};void ConcreteProductA::display(){log("display ConcreteProductA");}class ConcreteProductB:public priduct  //具体产品类B{public:void display();};void ConcreteProductB::display(){log("display ConcreteProductB");}class Factory //抽象工厂类{public:virtual product* Create(ProductId id); };class ConcreteFactory:public Factory //具体工厂类{public:product* Create(ProductId id);};product* ConcreteFactory::Create(ProductId id){if(id == PRODUCTA){return new ConcreteProductA();}else if(id == PRODUCTB){return new ConcreteProductB();}else {...}}//客户端如下int main(){Product pd = NULL;pd = ConcreteFactory.Create(PRODUCTB);//创建ConcreteProductBpd.display();return 0;}

(2)总结

1)工厂类包含必要的逻辑判断,同时也表明承担的职责过重,违反单一原则;
2)系统扩展困难,一旦添加产品必须修改工厂类的逻辑,不利于扩展和维护。

(3)适用场景

1)工厂类负责创建的对象比较少;
2)客户端只知道传入工厂类的参数,不关心如何创建。

2.工厂方法

在简单工厂模式中,如要要增加一个产品类,则需要修改工厂类的创建方法,违背了开闭原则。在工厂方法中,不再提供一个统一的工厂类来创建所有的产品对象,针对不同的产品提供不同的工厂,系统提供一个与产品等级结构对应的工厂等级结构

(1)定义

工厂方法:定义一个用于创建产品的接口或基类,让子类决定将哪一个类实例化。工厂方法模式让一个类的实例化延迟到其子类。工厂方法又称工厂模式。

它的结构图如下:


1)Product:定义工厂方法所创建的对象的接口;
2)ConcreteProduct:实现Product接口;
3)Fractory:声明工厂方法,返回一个Product类型对象;
4)ConcreteFactory:重定义工厂方法以返回一个ConcreteProduct对象。

以上架构框结构图的伪代码如下,Product部分和简单工厂代码一样:

class Factory //抽象工厂类{public:virtual product* Create(); };class ConcreteFactoryA:public Factory //具体工厂类A{public:product* Create();};product* ConcreteFactoryA::Create(){return new ConcreteProductA();}class ConcreteFactoryB:public Factory //具体工厂类B{public:product* Create();};product* ConcreteFactoryB::Create(){return new ConcreteProductB();}//客户端如下int main(){Product pdA = NULL;pdA = ConcreteFactoryA.Create();//创建ConcreteProductApdA.display();Product pdB = NULL;pdB = ConcreteFactoryB.Create();//创建ConcreteProductBpdB.display();return 0;}

下面再来看一个工厂方法的隐藏,客户端无需调用工厂方法创建产品,直接通过工厂既可以使用所创建的对象中的业务方法:


结构图的伪代码如下,Product部分和简单工厂代码一样:
class Factory //抽象工厂类{public:virtual product* Create();void display(); //product 方法};void Factory::display()  //product 方法{Product pd = this.Create(); //由子类创建pd.display();}class ConcreteFactoryA:public Factory //具体工厂类A{public:product* Create();};product* ConcreteFactoryA::Create(){return new ConcreteProductA();}class ConcreteFactoryB:public Factory //具体工厂类B{public:product* Create();};product* ConcreteFactoryB::Create(){return new ConcreteProductB();}

(2)总结

1)工厂方法是简单工厂的延伸,继承了他的优点,是使用频率最高的设计模式之一;
2)基于工厂角色和产品角色的多态性设计是关键;
3)新加入产品,无需更改原有代码,只需添加一个对应的具体工厂和具体产品就可以;
4)扩展需要同时加入具体工厂和具体产品,类个数将成对增加,会增加系统的复杂性。

(3)适用场景

1)客户端不知道他所需要的具体产品对象的类,只需要知道所对应的工厂即可;
2)当一个类希望由他的子类来指定它所创建的对象的时候;
3)抽象工厂类提供创建产品的接口,通过其子类来指定创建哪个对象,利用面向对象的多态性和里氏代换原则,在程序运行时,子类对象将覆盖父类对象,从而使得系统更容易扩展。


0 0