文章目录
- 核心: 多态
- 1. 简单工厂
- 1.1. 什么是简单工厂模式?
- 1.2. 模式中包含的角色与职责
- 1.3. 简单工厂的优缺点
- 1.4. 示例
- 2. 工厂模式
- 2.1. 概念
- 2.2. 类图角色和职责
- 2.3. 工厂方法模式和简单工厂模式比较
- 2.4. 示例
- 3. 抽象工厂
- 3.1. 概念
- 3.2. 产品族和产品等级结构
- 3.3. 模式中包含的角色和职责
- 3.4. 示例
核心: 多态
1. 简单工厂
1.1. 什么是简单工厂模式?
简单工厂模式属于类的创建型模式,又叫做静态工厂方法模式。通过专门定义一个类来负责创建其他类的实例,被创建的实例通常都具有共同的父类。
1.2. 模式中包含的角色与职责
- 工厂(Creator)角色
简单工厂模式的核心,它负责实现创建所有实例的内部逻辑。工厂类可以被外界直接调用,创建所需的产品对象。 - 抽象(Product)角色
简单工厂模式所创建的所有对象的父类,它负责描述所有实例所共有的公共接口。 - 具体产品(Concrete Product)角色
简单工厂模式所创建的具体实例对象
//依赖: 一个类的对象 当另外一个类的函数参数 或者是 返回值
1.3. 简单工厂的优缺点
在这个模式中,工厂类是整个模式的关键所在。它包含必要的判断逻辑,能够根据外界给定的信息,决定究竟应该创建哪个具体类的对象。用户在使用时可以直接根据工厂类去创建所需的实例,而无需了解这些对象是如何创建以及如何组织的。有利于整个软件体系结构的优化。不难发现,简单工厂模式的缺点也正体现在其工厂类上,由于工厂类集中了所有实例的创建逻辑,所以“高内聚”方面做的并不好。另外,当系统中的具体产品类不断增多时,可能会出现要求工厂类也要做相应的修改,扩展性并不很好。
1.4. 示例
// 适合: 工厂创建的类少, 创建的类少, 业务逻辑不复杂
// 客户端只知道传入工厂类的参数, 对于如何创建
// 客户端不需要知道对象类,
#include <iostream>
using namespace std;
class AbstractFruit{
public:
virtual void fruit() = 0;
};
class Apple: public AbstractFruit{
public:
virtual void fruit(){
cout<<"这是一个苹果"<<endl;
}
};
class Banana: public AbstractFruit{
public:
virtual void fruit(){
cout<<"这是一个香蕉"<<endl;
}
};
class Pear: public AbstractFruit{
public:
virtual void fruit(){
cout<<"这是一个鸭梨"<<endl;
}
};
// 水果工厂, 但是不符合开闭原则, 因为当前的工厂负责了全部类型水果, 所以
// 可以创建一个抽象工厂, 每个水果对应一个工厂, 这些工程用一个抽象工厂来管理, 这样就符合开闭原则
// 但是只要增加一个水果, 就要增加一个工厂, 这样会导致类越来越多, 增加维护成本
//
class FruitFactory{
public:
static AbstractFruit* Create(string flag){
if(flag == "apple"){
return new Apple;
}else if(flag == "banana"){
return new Banana;
}else{
return new Pear;
}
}
};
int main(int argc, char const *argv[])
{
// 创建过程不需要关心
FruitFactory* fatory = new FruitFactory();
AbstractFruit* apple = fatory->Create("apple");
apple->fruit();
delete apple;
delete fatory;
AbstractFruit* pear = FruitFactory::Create("pear");
pear->fruit();
delete pear;
return 0;
}
2. 工厂模式
2.1. 概念
工厂方法模式同样属于类的创建型模式又被称为多态工厂模式 。工厂方法模式的意义是定义一个创建产品对象的工厂接口,将实际创建工作推迟到子类当中。
核心工厂类不再负责产品的创建,这样核心类成为一个抽象工厂角色,仅负责具体工厂子类必须实现的接口,这样进一步抽象化的好处是使得工厂方法模式可以使系统在不修改具体工厂角色的情况下引进新的产品。
2.2. 类图角色和职责
- 抽象工厂(Creator)角色
工厂方法模式的核心,任何工厂类都必须实现这个接口。 - 具体工厂( Concrete Creator)角色
具体工厂类是抽象工厂的一个实现,负责实例化产品对象。 - 抽象(Product)角色
工厂方法模式所创建的所有对象的父类,它负责描述所有实例所共有的公共接口。 - 具体产品(Concrete Product)角色
工厂方法模式所创建的具体实例对象
2.3. 工厂方法模式和简单工厂模式比较
工厂方法模式与简单工厂模式在结构上的不同不是很明显。工厂方法类的核心是一个抽象工厂类,而简单工厂模式把核心放在一个具体类上。
工厂方法模式之所以有一个别名叫多态性工厂模式是因为具体工厂类都有共同的接口,或者有共同的抽象父类。
当系统扩展需要添加新的产品对象时,仅仅需要添加一个具体对象以及一个具体工厂对象,原有工厂对象不需要进行任何修改,也不需要修改客户端,很好的符合了“开放-封闭”原则。而简单工厂模式在添加新产品对象后不得不修改工厂方法,扩展性不好。工厂方法模式退化后可以演变成简单工厂模式。
“开放-封闭”通过添加代码的方式,不是通过修改代码的方式完成功能的增强。
2.4. 示例
#include <iostream>
using namespace std;
class AbstractFruit{
public:
virtual void fruit() = 0;
};
class Apple: public AbstractFruit{
public:
virtual void fruit(){
cout<<"这是一个苹果"<<endl;
}
};
class Banana: public AbstractFruit{
public:
virtual void fruit(){
cout<<"这是一个香蕉"<<endl;
}
};
class Pear: public AbstractFruit{
public:
virtual void fruit(){
cout<<"这是一个鸭梨"<<endl;
}
};
// 简单的水果工厂, 直接生产各种水果
class FruitFactory{
public:
static AbstractFruit* Create(string flag){
if(flag == "apple"){
return new Apple;
}else if(flag == "banana"){
return new Banana;
}else{
return new Pear;
}
}
};
// 水果工厂 , 每个水果都增加一个抽象类
class AbstractFruitFactory{
public:
virtual AbstractFruit* Create()=0;
};
// 苹果工厂
class AppleFactory : public AbstractFruitFactory{
public:
virtual AbstractFruit* Create(){
return new Apple;
}
};
// 香蕉工厂
class BananaFactory : public AbstractFruitFactory{
public:
virtual AbstractFruit* Create(){
return new Banana;
}
};
// 冯雷工厂
class PearFactory : public AbstractFruitFactory{
public:
virtual AbstractFruit* Create(){
return new Pear;
}
};
int main(int argc, char const *argv[])
{
// 创建过程不需要关心
FruitFactory* fatory = new FruitFactory();
AbstractFruit* apple = fatory->Create("apple");
apple->fruit();
delete apple;
delete fatory;
AbstractFruitFactory* factory1 = NULL; // 创建一个工厂
AbstractFruit *fruit1 = NULL; // 创建一个水果工厂
factory1 = new AppleFactory(); // 这个工厂是一个苹果工厂
fruit1 = factory1->Create(); // 利用苹果工厂创建一个苹果
fruit1->fruit();
delete fruit1;
delete factory1;
return 0;
}
3. 抽象工厂
3.1. 概念
抽象工厂模式是所有形态的工厂模式中最为抽象和最其一般性的。抽象工厂模式可以向客户端提供一个接口,使得客户端在不必指定产品的具体类型的情况下,能够创建多个产品族的产品对象。
3.2. 产品族和产品等级结构
备注1:
工厂模式:要么生产香蕉、要么生产苹果、要么生产西红柿;但是不能同时生产一个产品组。抽象工厂:能同时生产一个产品族。===》抽象工厂存在原因
解释: 具体工厂在开闭原则下, 能生产香蕉/苹果/梨子; (产品等级结构)
抽象工厂:在开闭原则下, 能生产:南方香蕉/苹果/梨子 (产品族)
北方香蕉/苹果/梨子
重要区别:
工厂模式只能生产一个产品。(要么香蕉、要么苹果)
抽象工厂可以一下生产一个产品族(里面有很多产品组成)
3.3. 模式中包含的角色和职责
- 抽象工厂(Creator)角色
抽象工厂模式的核心,包含对多个产品结构的声明,任何工厂类都必须实现这个接口。 - 具体工厂( Concrete Creator)角色
具体工厂类是抽象工厂的一个实现,负责实例化某个产品族中的产品对象。 - 抽象(Product)角色
抽象模式所创建的所有对象的父类,它负责描述所有实例所共有的公共接口。 - 具体产品(Concrete Product)角色
抽象模式所创建的具体实例对象
3.4. 示例
// 抽象工厂针对产品族, 而不是产品等级结构
// 产品族: 同一个产地或者同一个工厂, 功能不同
// 产品等级: 功能相同, 厂商或者产地不同
// 中国工程: 苹果,鸭梨,香蕉:
// 美国工程: 苹果,鸭梨,香蕉:
// 鬼子工程: 苹果,鸭梨,香蕉:
#include <iostream>
using namespace std;
// 抽象苹果
class AbstractApple{
public:
virtual void showName() = 0;
};
class ChinaApple: public AbstractApple{
public:
virtual void showName(){
cout<<"中国苹果.."<<endl;
}
};
class USApple: public AbstractApple{
public:
virtual void showName(){
cout<<"美国苹果.."<<endl;
}
};
class JPApple: public AbstractApple{
public:
virtual void showName(){
cout<<"日本苹果.."<<endl;
}
};
// 抽象香蕉
class AbstractBanana{
public:
virtual void showName() = 0;
};
class ChinaBanana: public AbstractBanana{
public:
virtual void showName(){
cout<<"中国香蕉.."<<endl;
}
};
class USBanana: public AbstractBanana{
public:
virtual void showName(){
cout<<"美国香蕉.."<<endl;
}
};
class JPBanana: public AbstractBanana{
public:
virtual void showName(){
cout<<"日本香蕉.."<<endl;
}
};
// 抽象鸭梨
class AbstractPear{
public:
virtual void showName() = 0;
};
class ChinaPear: public AbstractPear{
public:
virtual void showName(){
cout<<"中国鸭梨.."<<endl;
}
};
class USPear: public AbstractPear{
public:
virtual void showName(){
cout<<"美国鸭梨.."<<endl;
}
};
class JPPear: public AbstractPear{
public:
virtual void showName(){
cout<<"日本鸭梨.."<<endl;
}
};
// 抽象工厂
class AbstractFactory{
public:
virtual AbstractApple* createApple() = 0;
virtual AbstractBanana* createBanana() = 0;
virtual AbstractPear* createPear() = 0;
};
// 中国工厂
class ChinaFactory: public AbstractFactory{
public:
virtual AbstractApple* createApple(){return new ChinaApple;}
virtual AbstractBanana* createBanana(){return new ChinaBanana;}
virtual AbstractPear* createPear(){return new ChinaPear;}
};
// 美国工厂
class USFactory: public AbstractFactory{
public:
virtual AbstractApple* createApple(){return new USApple;}
virtual AbstractBanana* createBanana(){return new USBanana;}
virtual AbstractPear* createPear(){return new USPear;}
};
// 日本工厂
class JPFactory: public AbstractFactory{
public:
virtual AbstractApple* createApple(){return new JPApple;}
virtual AbstractBanana* createBanana(){return new JPBanana;}
virtual AbstractPear* createPear(){return new JPPear;}
};
void test01(){
AbstractFactory* factory = NULL;
AbstractApple* apple = NULL;
AbstractBanana* banan = NULL;
AbstractPear* pear = NULL;
factory = new ChinaFactory(); // 想吃中国工厂生产的水果就先建一个中国工厂
apple = factory->createApple(); // 中国工厂生产一个aplle;
banan = factory->createBanana();
pear = factory->createPear();
apple->showName(); // 吃掉这个苹果
banan->showName(); // 吃掉这个苹果
pear->showName(); // 吃掉这个苹果
delete apple;
delete banan;
delete pear;
delete factory;
}
int main(int argc, char const *argv[]){
test01();
cout<<"hello"<<endl;
return 0;
}