模式的问题:你如何能轻松方便地构造对象实例,而没必要关心构造对象实例的细节和复杂过程呢?ios
解决方案:创建一个工厂来建立对象。 固然也能够根据不一样的状况,采用建造者模式或者原型模式,总之,你须要另外一个建立者角色对象来帮助你产生建立构造对象实例。这里咱们将工厂模式。c++
工厂模式能够分为三类:设计模式
这三种模式从上到下逐步抽象,而且更具通常性。GOF在《设计模式》一书中将工厂模式分为两类:工厂方法模式(Factory Method)与抽象工厂模式(Abstract Factory)。将简单工厂模式(Simple Factory)看为工厂方法模式的一种特例,二者归为一类。bash
模式 | 描述 |
---|---|
工厂方法模式 | 一个抽象产品类,能够派生出多个具体产品类。一个抽象工厂类,能够派生出多个具体工厂类。每一个具体工厂类只能建立一个具体产品类的实例。 |
抽象工厂模式 | 多个抽象产品类,每一个抽象产品类能够派生出多个具体产品类。一个抽象工厂类,能够派生出多个具体工厂类。每一个具体工厂类能够建立多个具体产品类的实例。 |
工厂方法模式与抽象工厂模式的区别——工厂方法模式只有一个抽象产品类,而抽象工厂模式有多个。 工厂方法模式的具体工厂类只能建立一个具体产品类的实例,而抽象工厂模式能够建立多个。 。函数
简单工厂模式又称静态工厂方法模式。从命名上就能够看出这个模式必定很简单。它存在的目的很简单:定义一个用于建立对象的接口。 单元测试
#include "stdafx.h"
#include <iostream>
#include <vector>
using namespace std;
typedef enum ProductTypeTag
{
TypeA,
TypeB,
TypeC
}PRODUCTTYPE;
// Here is the product class
class Product {
public:
virtual void Show() = 0;
};
class ProductA : public Product
{
public:
void Show() {
cout<<"I'm ProductA"<<endl;
}
};
class ProductB : public Product
{
public:
void Show() {
cout<<"I'm ProductB"<<endl;
}
};
class ProductC : public Product
{
public:
void Show() {
cout<<"I'm ProductC"<<endl;
}
};
// Here is the Factory class
class Factory {
public:
Product* CreateProduct(PRODUCTTYPE type) {
switch (type)
{
case TypeA:
return new ProductA();
case TypeB:
return new ProductB();
case TypeC:
return new ProductC();
default:
return NULL;
}
}
};
复制代码
#include<memory>
#include "simple_factory.h"
using namespace std;
int main() {
// First, create a factory object
std::unique_ptr<Factory> ProductFactory(new Factory);
std::unique_ptr<Product> productObjA(ProductFactory->CreateProduct(TypeA));
productObjA->Show();
std::unique_ptr<Product> productObjB(ProductFactory->CreateProduct(TypeB));
productObjB->Show();
std::unique_ptr<Product> productObjC(ProductFactory->CreateProduct(TypeC));
productObjC->Show();
return 0;
}
复制代码
以前讲到了简单工厂模式,因为简单工厂模式的局限性,好比:工厂如今能生产ProductA、ProductB和ProductC三种产品了,此时,须要增长生产ProductD产品;那么,首先是否是须要在产品枚举类型中添加新的产品类型标识,而后,修改Factory类中的switch结构代码。是的,这种对代码的修改,对原有代码的改动量较大,易产生编码上的错误(虽然很简单,若是工程大了,出错也是在所不免的!)。这种对代码的修改是最原始,最野蛮的修改,本质上不能称之为对代码的扩展。同时,因为对已经存在的函数进行了修改,那么之前进行过的测试,都将是无效的,全部的测试,都将须要从新进行,全部的代码都须要进行从新覆盖。这种,增长成本,不能提升效率的事情,在公司是绝对不容许的。出于种种缘由,简单工厂模式,在实际项目中使用的较少。那么该怎么办?怎么办呢?须要对原有代码影响降到最小,同时能对原有功能进行扩展。 测试
工厂方法模式的意义是定义一个建立产品对象的工厂接口,将实际建立工做推迟到子类当中。核心工厂类再也不负责产品的建立,这样核心类成为一个抽象工厂角色,仅负责具体工厂子类必须实现的接口,这样进一步抽象化的好处是使得工厂方法模式可使系统在不修改具体工厂角色的状况下引进新的产品。ui
因为使用设计模式是在详细设计时,就须要进行定夺的,因此,须要权衡多方面的因素,而不能为了使用设计模式而使用设计模式。编码
#include "stdafx.h"
#include <iostream>
#include <vector>
using namespace std;
// Here is the product class
class Product
{
public:
virtual void Show() = 0;
};
class ProductA : public Product
{
public:
void Show()
{
cout<<"I'm ProductA"<<endl;
}
};
class ProductB : public Product
{
public:
void Show()
{
cout<<"I'm ProductB"<<endl;
}
};
class ProductC : public Product
{
public:
void Show()
{
cout<<"I'm ProductC"<<endl;
}
};
// Here is the Factory class
class Factory
{
public:
virtual Product* CreateProduct()=0;
};
class FactoryA:public Factory
{
public:
Product* CreateProduct()
{
return new ProductA;
}
};
class FactoryB:public Factory
{
public:
Product* CreateProduct()
{
return new ProductB;
}
};
class FactoryC:public Factory
{
public:
Product* CreateProduct()
{
return new ProductC;
}
};
复制代码
#include<memory>
#include "factory.h"
using namespace std;
int main(){
// First, create a factory object
Factory* ProductFactory=new FactoryA;
std::unique_ptr<Product> productObjA(ProductFactory->CreateProduct());
productObjA->Show();
ProductFactory = new FactoryB;
std::unique_ptr<Product> productObjB(ProductFactory->CreateProduct());
productObjB->Show();
ProductFactory = new FactoryC;
std::unique_ptr<Product> productObjC(ProductFactory->CreateProduct());
productObjC->Show();
delete ProductFactory;
return 0;
}
复制代码
这样后期若是想增长产品D或者删除已有产品C对原有程序改动(范围)都很是小。spa
以前讲到了工厂方法模式,咱们可能会想到,后期产品会愈来愈多了,创建的工厂也会愈来愈多,工厂进行了增加,工厂变的凌乱而难于管理;因为工厂方法模式建立的对象都是继承于Product的,因此工厂方法模式中,每一个工厂只能建立单一种类的产品,当须要生产一种全新的产品(不继承自Product)时,发现工厂方法是爱莫能助。
举个例子来讲:一个显示器电路板厂商,旗下的显示器电路板种类有非液晶的和液晶的;这个时候,厂商建造两个工厂,工厂A负责生产非液晶显示器电路板,工厂B负责生产液晶显示器电路板;工厂一直就这样运行着。有一天,总经理发现,直接生产显示器的其他部分也挺挣钱,因此,总经理决定,再创建两个工厂C和D;C负责生产非液晶显示器的其他部件,D负责生产液晶显示器的其他部件。此时,旁边参谋的人就说了,经理,这样作很差,咱们能够直接在工厂A中添加一条负责生产非液晶显示器的其他部件的生产线,在工厂B中添加一条生产液晶显示器的其他部件的生产线,这样就能够不用增长厂房,只用将现有厂房进行扩大一下,同时也方便工厂的管理,并且生产非液晶显示器电路板的技术人员对非液晶显示的其他部件的生产具备指导的做用,生产液晶显示器电路板也是同理。总经理发现这是一个不错的主意。
再回到软件开发的过程当中来,工厂A和B就是以前所说的设计模式——工厂方法模式;总经理再次创建工厂C和D,就是重复设计模式——工厂方法模式,只是生产的产品不一样罢了。这样作的弊端就如参谋所说的那样,增长了管理成本和人力成本。在面向对象开发的过程当中,是很注重对象管理和维护的,对象越多,就越难进行管理和维护;若是工厂数量过多,那么管理和维护的成本将大大增长;虽然生产的是不一样的产品,可是能够两者之间是有微妙的关系的,如参谋所说,技术人员的一些技术经验是能够借鉴的,这就至关于同一个类中的不一样对象,之间是能够公用某些资源的。那么,增长一条流水线,扩大厂房,固然是最好的主意了。
实际问题已经获得了解决,那么如何使用设计模式模拟这个实际的问题呢?那就是接下来所说的抽象工厂模式。
抽象工厂模式,就是工厂方法模式的扩展和延伸,可是抽象工厂模式,更有通常性和表明性;它具备工厂方法具备的优势,也增长了解决实际问题的能力。
工厂方法模式适用于产品种类结构单一的场合,为一类产品提供建立的接口;而抽象工厂方法适用于产品种类结构多的场合,主要用于建立一组(有多个种类)相关的产品,为它们提供建立的接口;就是当具备多个抽象角色时,抽象工厂即可以派上用场。
#pragma once
#include <iostream>
using namespace std;
// Product A
class ProductA {
public:
virtual void Show() = 0;
};
class ProductA1 : public ProductA
{
public:
void Show() {
cout << "I'm ProductA1" << endl;
}
};
class ProductA2 : public ProductA
{
public:
void Show() {
cout << "I'm ProductA2" << endl;
}
};
// Product B
class ProductB {
public:
virtual void Show() = 0;
};
class ProductB1 : public ProductB
{
public:
void Show() {
cout << "I'm ProductB1" << endl;
}
};
class ProductB2 : public ProductB
{
public:
void Show() {
cout << "I'm ProductB2" << endl;
}
};
// Factory
class Factory {
public:
virtual ProductA *CreateProductA() = 0;
virtual ProductB *CreateProductB() = 0;
};
class Factory1 : public Factory
{
public:
ProductA *CreateProductA() {
return new ProductA1();
}
ProductB *CreateProductB() {
return new ProductB1();
}
};
class Factory2 : public Factory
{
ProductA *CreateProductA() {
return new ProductA2();
}
ProductB *CreateProductB() {
return new ProductB2();
}
};
复制代码
#include<memory>
#include"AbstractFactoryPattern.h"
int main() {
std::unique_ptr<Factory> facObj1(new Factory1);
std::unique_ptr<ProductA> proObjA1(facObj1->CreateProductA());
std::unique_ptr<ProductB> proObjB1(facObj1->CreateProductB());
proObjA1->Show();
proObjB1->Show();
std::unique_ptr<Factory> facObj2(new Factory2);
std::unique_ptr<ProductA> proObjA2(facObj2->CreateProductA());
std::unique_ptr<ProductB> proObjB2(facObj2->CreateProductB());
proObjA2->Show();
proObjB2->Show();
return 0;
}
复制代码