本文是我学习刘伟技术博客的笔记,博客链接如下:
http://blog.csdn.net/lovelion/article/details/17517213
我做的这部分笔记,鉴于自身水平有限,我只是对上面博客内做进一步提炼和记录,方便自己查阅。同时,更多的是对设计模式的框架进行学习,大部分细节都将略去,让自己侧重对每个设计模式框架的理解。
我应该理解和掌握的:
1)能够画出这个设计模式的架构框图;
2)能够根据架构框图写出对应的伪代码;
3)这个模式的应用场景,主要优缺点。
1.抽象工厂
与工厂方法相比,抽象工厂模式中的具体工厂不只是创建一种产品,他负责创建一族产品。
(1)定义
抽象工厂模式:提供一个创建一系列相关或相互依赖对象的接口,而无需指定他们具体的类。别名又称Kit模式。
抽象工厂模式中,每一个具体工厂都提供了多个工厂方法用于产生多种不同类型的产品,这些产品构成一个产品族,像代码里面的1系列。
下面是结构图,需要知道每个类扮演的角色和作用:
每个类的角色:
1)AbstractFactory(抽象工厂):声明一组用于创建一族抽象产品的方法,每一个方法对应一种产品。
2)ConcreteFactory(具体工厂):实现创建具体产品对象的操作。
3)AbstractProduct(抽象产品):为一类产品对象声明一个接口或方法。
4)ConcreteProduct(具体产品):定义具体工厂生产的具体产品对象,实现抽象产品接口中声明的业务方法。
5)Client(客户端):仅使用由AbstractProduct和AbstractFactory类声明的接口。
抽象工厂框架图,看图写代码:
//AbstractProductA
class AbstractProductA
{
public:
/*C++通过使用纯虚函数提供未实现的函数,纯虚函数在结尾处为=0。
当类声明中包含纯虚函数时,则不能创建该类的对象。纯虚函数,可定义可不定义*/
virtual void display() = 0;
};
//ConcreteProductA1
class ConcreteProductA1:public AbstractProductA
{
public:
virtual void display();
};
void ConcreteProductA1::display()
{
cout<<"this is A1\n";
}
//ConcreteProductA2
class ConcreteProductA2:public AbstractProductA
{
public:
virtual void display();
};
void ConcreteProductA2::display()
{
cout<<"this is A2\n";
}
//AbstractProductB
class AbstractProductB
{
public:
/*C++通过使用纯虚函数提供未实现的函数,纯虚函数在结尾处为=0。
当类声明中包含纯虚函数时,则不能创建该类的对象。纯虚函数,可定义可不定义*/
virtual void display() = 0;
};
//ConcreteProductB1
class ConcreteProductB1:public AbstractProductB
{
virtual void display();
};
void ConcreteProductB1::display()
{
cout<<"this is B1\n";
}
//AbstractFactory
class AbstractFactory
{
public:
/*在抽象工厂中,声明多个工厂方法,用于创建不同类型的产品*/
virtual AbstractProductA* createProductA() = 0; //声明创建产品A
virtual AbstractProductB* createProductB() = 0; //声明创建产品B
};
//ConcreteFactory1
class ConcreteFactory1:public AbstractFactory
{
virtual AbstractProductA* createProductA();
virtual AbstractProductB* createProductB();
};
/*具体工厂实现抽象工厂,返回特定的产品对象*/
AbstractProductA* ConcreteFactory1::createProductA()
{
return new ConcreteProductA1();
}
AbstractProductB* ConcreteFactory1::createProductB()
{
return new ConcreteProductB1();
}
//ConcreteFactory2
class ConcreteFactory2:public AbstractFactory
{
virtual AbstractProductA* createProductA();
virtual AbstractProductB* createProductB();
};
AbstractProductA* ConcreteFactory2::createProductA()
{
return new ConcreteProductA2();
}
AbstractProductB* ConcreteFactory2::createProductB()
{
return new ConcreteProductB2();
}
//Client
#include<iostream>
#include "ConcreteFactory1.h"
#include "ConcreteFactory2.h"
#include "ConcreteProductA1.h"
#include "ConcreteProductA2.h"
#include "ConcreteProductB1.h"
#include "ConcreteProductB2.h"
using namespace std;
int main()
{
//声明抽象工厂和抽象产品类
AbstractProductA *pA1, *pA2;
AbstractProductB *pB1, *pB2;
AbstractFactory *ft1, *ft2;
//创建具体工厂类
ft1 = new ConcreteFactory1();//创建1系列产品,即A1,B1产品
ft2 = new ConcreteFactory2();//创建2系列产品,即A2,B2产品
//不同的具体工厂创建出不同具体产品类
//1系列产品对象
pA1 = ft1->createProductA();
pB1 = ft1->createProductB();
pA1->display();
pB1->display();
//2系列产品对象
pA2 = ft2->createProductA();
pB2 = ft2->createProductB();
pA2->display();
pB2->display();
return 0;
}
(2)总结
1)隔离了具体类的生成,是的客户并不需要知道什么被创建。客户通过他们的抽象接口操纵实例,产品的类名也在具体工厂的实现中被分离,不出现在客户端代码中。
2)增加新的产品族方便,无需修改原有系统,符合开闭原则。
3)增加新的产品等级结构麻烦,需要修改抽象层代码。
4)当一个系列中的产品对象被设计成一起工作时,一个应用只能使用同一个系列中的对象。
(3)使用场景
1)一个系统要独立于他的产品的创建、组合和表示时。用户无需关心对象的创建过程,将对象的创建和使用解耦。
2)一个系统要由多个产品系列中的一个来配置时;系统中有多于一个的产品族,而每次只使用其中某一类产品族。
3)当你要强调一系列相关的产品对象的设计以便进行联合使用时。//暂时不理解
4)当你提供一个产品类库,而只想显示他们的接口而不是实现时。//暂时不理解
5)产品等级结构稳定,设计完成后,不会向系统中增加新的产品等级结构或者删除已有的产品等级结构。