设计模式学习--抽象工厂模式
来源:互联网 发布:网络火的歌曲有哪些 编辑:程序博客网 时间:2024/06/10 19:17
设计模式学习–抽象工厂模式
文章理论部分参考以下链接
http://www.runoob.com/design-pattern/abstract-factory-pattern.html
一、 抽象工厂模式介绍
抽象工厂模式(Abstract Factory Pattern)是围绕一个超级工厂创建其他工厂。该超级工厂又称为其他工厂的工厂。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。在抽象工厂模式中,接口是负责创建一个相关对象的工厂,不需要显式指定它们的类。每个生成的工厂都能按照工厂模式提供对象。
意图:提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。
主要解决:主要解决接口选择的问题。
何时使用:系统的产品有多于一个的产品族,而系统只消费其中某一族的产品。
如何解决:在一个产品族里面,定义多个产品。
关键代码:在一个工厂里聚合多个同类产品。
应用实例:工作了,为了参加一些聚会,肯定有两套或多套衣服吧,比如说有商务装(成套,一系列具体产品)、时尚装(成套,一系列具体产品),甚至对于一个家庭来说,可能有商务女装、商务男装、时尚女装、时尚男装,这些也都是成套的,即一系列具体产品。假设一种情况(现实中是不存在的,要不然,没法进入共产主义了,但有利于说明抽象工厂模式),在您的家中,某一个衣柜(具体工厂)只能存放某一种这样的衣服(成套,一系列具体产品),每次拿这种成套的衣服时也自然要从这个衣柜中取出了。用 OO 的思想去理解,所有的衣柜(具体工厂)都是衣柜类的(抽象工厂)某一个,而每一件成套的衣服又包括具体的上衣(某一具体产品),裤子(某一具体产品),这些具体的上衣其实也都是上衣(抽象产品),具体的裤子也都是裤子(另一个抽象产品)。
优点:当一个产品族中的多个对象被设计成一起工作时,它能保证客户端始终只使用同一个产品族中的对象。
缺点:产品族扩展非常困难,要增加一个系列的某一产品,既要在抽象的 Creator 里加代码,又要在具体的里面加代码。
使用场景: 1、QQ 换皮肤,一整套一起换。 2、生成不同操作系统的程序。
注意事项:产品族难扩展,产品等级易扩展。
抽象基类:
1、AbstractProductA,AbstractProductB:分别代表不同类型的产品,而它们的派生类则是这种产品的一个实现.
2、AbstractFactory:生产这一系列产品的一个抽象工厂,它的派生类是不同的实现.
接口函数:
1、AbstractFactory::CreateProductA 和 AbstractFactory::CreateProductB:
分别是生产不同产品的不同的实现,由各个派生出来的抽象工厂实现之.
解析:
Abstract Factory 模式和 Factory 最大的差别就是抽象工厂创建的是一系列相关的对象,其中创建的实现其实采用的就是 Factory 模式的方法,对于某个实现的有一个派生出来的抽象工厂,另一个实现有另一个派生出来的工厂,等等。
可以再举一个简单的例子来解释这个模式:比如,同样是纯牛奶(AbstractProductA)和高钙奶(AbstractProductB),它们都可以有商店出售(AbstractFactory),但是有不同的实现,有蒙牛(ConcreateFactory1)和伊利(ConcreateFactory2)两家生产出来的不同风味的纯牛奶和高钙奶,但可以明确的是,我们在购买牛奶套餐装,得到的都是一个风味的纯牛奶和高钙奶,因为他们产于同一个具体工厂。而这里负责生产纯牛奶和高钙奶的就是之前提过的 Factory 模式了。
抽象工厂需要特别注意的地方就是区分不同类型的产品和这些产品的不同实现.显而易见的,如果有 n 种产品同时有 m 中不同的实现,那么根据乘法原理可知有 n*m 个
Factory 模式的使用。
二、实现演示
1、创建两个产品的抽象基类
//纯牛奶的抽象基类class AbstractProductA{public: AbstractProductA(){} virtual ~AbstractProductA(){}};//高钙奶的抽象基类class AbstractProductB{public: AbstractProductB(){} virtual ~AbstractProductB(){}};
2、创建具体产品类,继承抽象基类
//蒙牛的纯牛奶class ProductA1:public AbstractProductA{public: ProductA1() { cout<<"construction of ProductA1"<<endl; } virtual ~ProductA1() { cout<<"destruction of ProductA1"<<endl; }};//伊利的纯牛奶class ProductA2:public AbstractProductA{public: ProductA2() { cout<<"construction of ProductA2"<<endl; } virtual ~ProductA2() { cout<<"destruction of ProductA2"<<endl; }};//蒙牛的高钙奶class ProductB1:public AbstractProductB{public: ProductB1() { cout<<"construction of ProductB1"<<endl; } virtual ~ProductB1() { cout<<"destruction of ProductB1"<<endl; }};//伊利的高钙奶class ProductB2:public AbstractProductA{public: ProductB2() { cout<<"construction of ProductB2"<<endl; } virtual ~ProductB2() { cout<<"destruction of ProductB2"<<endl; }};
3、创建一个抽象工厂类,生产纯牛奶和高钙奶
class AbstractFactory{public: AbstractFactory(){} virtual ~AbstractFactory(){} virtual AbstractProductA* CreateProductA()=0; virtual AbstractProductB* CreateProductB()=0;};
4、 实现 ConcreteFactory_MN和 ConcreteFactory_YL
// 派生类 ConcreteFactory_MN,继承自 AbstractFactory,生产产品A和产品B的第一种实现class ConcreteFactory_MN:public AbstractFactory{public: ConcreteFactory_MN() { cout<<"ConcreteFactory_MN"<<endl; } virtual ~ConcreteFactory_MN(){} virtual AbstractProductA* CreateProductA() { return new ProductA1(); } virtual AbstractProductB* CreateProductB() { return new ProductB1(); }}// 派生类 ConcreteFactory_YL,继承自 AbstractFactory,生产产品A和产品B的第一种实现class ConcreteFactory_YL:public AbstractFactory{public: ConcreteFactory_YL() { cout<<"ConcreteFactory_YL"<<endl; } virtual ~ConcreteFactory_YL(){} virtual AbstractProductA* CreateProductA() { return new ProductA2(); } virtual AbstractProductB* CreateProductB() { return new ProductB2(); }}
5、客户或者调用者
int main(){ //生产产品A的第一种实现 AbstractFactory *cf1 = new ConcreteFactory1(); cf1->CreateProductA(); //生产产品B的第二种实现 AbstractFactory *cf2 = new ConcreteFactory2(); cf2->CreateProductB(); delete cf1; delete cf2; return 0;}
三、扩展性测试
从上述过程可以看出,如果需要增加一个产品(例如新添一个香蕉牛奶),我需要以下代码
//香蕉牛奶的抽象基类class AbstractProductC{public: AbstractProductC(){} virtual ~AbstractProductC(){}};//新的具体产品类,蒙牛和伊利都会生产class ProductC1:public Product{public: ProductC1() { cout<<"construction of ProductC1"<<endl; } virtual ~ProductC1() { cout<<"destruction of ProductC1"<<endl; }};class ProductC2:public Product{public: ProductC2() { cout<<"construction of ProductC2"<<endl; } virtual ~ProductC2() { cout<<"destruction of ProductC2"<<endl; }};//修改抽象工厂类class AbstractFactory{public: AbstractFactory(){} virtual ~AbstractFactory(){} virtual AbstractProductA* CreateProductA()=0; virtual AbstractProductB* CreateProductB()=0; virtual AbstractProductC* CreateProductC()=0; //新添函数};//修改两个具体工厂类class ConcreteFactory_MN:public AbstractFactory{public: ConcreteFactory_MN() { cout<<"ConcreteFactory_MN"<<endl; } virtual ~ConcreteFactory_MN(){} virtual AbstractProductA* CreateProductA() { return new ProductA1(); } virtual AbstractProductB* CreateProductB() { return new ProductB1(); } virtual AbstractProductC* CreateProductC() { return new ProductC1(); }};// 派生类 ConcreteFactory_YL,继承自 AbstractFactory,生产产品A和产品B的第一种实现class ConcreteFactory_YL:public AbstractFactory{public: ConcreteFactory_YL() { cout<<"ConcreteFactory_YL"<<endl; } virtual ~ConcreteFactory_YL(){} virtual AbstractProductA* CreateProductA() { return new ProductA2(); } virtual AbstractProductB* CreateProductB() { return new ProductB2(); } virtual AbstractProductC* CreateProductC() { return new ProductC2(); }};//客户拥有了新的选择int main(){ Factory *f; int type; cin>>type; switch(type) { case 1: f = new ConcreteFactory_MN(); break; case 2: f = new ConcreteFactory_YL(); break; } Product *p = f->CreateProductB(); //Product *p = f->CreateProductC(); delete p; delete f; return 0;}
可见添加一个新的产品,修改量很大。
整体代码:
//abstract_factory.cpp#include<iostream>using namespace std;//抽象基类AbstractProductA,代表产品A的抽象class AbstractProductA{public: AbstractProductA(){} virtual ~AbstractProductA(){}};//派生类ConcreateProductAl,继承自AbstractProductA,代表产品A的第一种实现class ConcreateProductA1:public AbstractProductA{public: ConcreateProductA1() { cout<<"ConcreateProdcutA1"<<endl; } virtual ~ConcreateProductA1(){}};//派生类ConcreateProductA2,继承自AbstractProductA,代表产品A的第二种实现class ConcreateProductA2:public AbstractProductA{public: ConcreateProductA2() { cout<<"ConcreateProductA2"<<endl; } virtual ~ConcreateProductA2(){}};//抽象基类AbstractProductB,代表产品B的抽象class AbstractProductB{public: AbstractProductB(){} virtual ~AbstractProductB(){}};//派生类ConcreateProductB1,继承自AbstractProductB,代表产品B的第一种实现class ConcreateProductB1:public AbstractProductB{public: ConcreateProductB1() { cout<<"ConcreateProductB1"<<endl; } virtual ~ConcreateProductB1(){}};//派生类ConcreateProductB2,继承自AbstractProductB,代表产品B的第二种实现class ConcreateProductB2:public AbstractProductB{public: ConcreateProductB2() { cout<<"ConcreateProductB2"<<endl; } virtual ~ConcreateProductB2(){}};//抽象基类AbstractFactory,工厂的抽象类,生产产品A和产品Bclass AbstractFactory{public: AbstractFactory(){} virtual ~AbstractFactory(){} virtual AbstractProductA* CreateProductA()=0; virtual AbstractProductB* CreateProductB()=0;};// 派生类 ConcreateFactoryl,继承自 AbstractFactory,生产产品A和产品B的第一种实现classConcreteFactory1:public AbstractFactory{public: ConcreteFactory1() { cout<<"ConcreteFactory1"<<endl; } virtual ~ConcreteFactory1(){} virtual AbstractProductA* CreateProductA() { return new ConcreateProductA1(); } virtual AbstractProductB* CreateProductB() { return new ConcreateProductB1(); }};// 派生类 ConcreateFactory2,继承自 AbstractFactory生产产品A和产品B的第二种实现classConcreteFactory2:public AbstractFactory{public: ConcreteFactory2() { cout<<"ConcreteFactory2"<<endl; } virtual ~ConcreteFactory2(){} virtual AbstractProductA* CreateProductA() { return new ConcreateProductA2(); } virtual AbstractProductB* CreateProductB() { return new ConcreateProductB2(); }};int main(){ //生产产品A的第一种实现 AbstractFactory *cf1 = new ConcreteFactory1(); cf1->CreateProductA(); //生产产品B的第二种实现 AbstractFactory *cf2 = new ConcreteFactory2(); cf2->CreateProductB(); delete cf1; delete cf2; return 0;}
- 设计模式学习--抽象工厂
- 设计模式学习----抽象工厂模式
- 设计模式之抽象工厂模式学习
- 设计模式学习-----抽象工厂模式
- 设计模式学习笔记-抽象工厂模式
- GoF设计模式学习-抽象工厂模式
- 设计模式学习—抽象工厂模式
- 学习设计模式之“抽象工厂模式”
- 设计模式学习笔记--抽象工厂模式
- 设计模式学习--抽象工厂模式
- 设计模式学习笔记-抽象工厂模式
- 设计模式实例学习-抽象工厂模式
- 设计模式深入学习-抽象工厂模式
- 设计模式学习--抽象工厂模式
- 【设计模式学习】抽象工厂模式
- 【设计模式学习】抽象工厂模式
- 设计模式学习:抽象工厂模式
- 设计模式学习---第九节:抽象工厂模式
- 日常mark
- 《kubernetes-1.8.0》17-examples-Running ZooKeeper
- 怎样通过pprof监控docker
- poj3321——Apple Tree
- ClassNotFoundException: org.springframework.web.context.ContextLoaderListener解决办法
- 设计模式学习--抽象工厂模式
- 2017/12/11
- Jquery获取Select选中控件的值
- 配置struts2以及struts2需要的包
- Freemarker2.3.23使用
- Retrofit之多文件多参数上传
- Java通过JDBC进行简单的增删改查(以MySQL为例)
- nrf52832 SPi方式无操作系统与SD卡通信
- HTTP状态码