系列总链接:https://blog.csdn.net/qq_22122811/article/details/112360387
参考:https://www.cnblogs.com/adamjwh/p/9033553.html
参考:https://www.cnblogs.com/ygsworld/p/10649491.html
一:概述
工厂二字想必大家都不陌生,工厂就是用来建造东西的,我们市面上买的东西比如水杯、玩具、汽车等等都是从工厂生产的,那我们需不需要知道它们是如何生产出来的呢?当然不需要,商家从工厂中直接提货,我们就可以购买了,完全不知道它是如何生产的,这就是工厂方法模式。
工厂模式分为:简单工厂模式,工厂方法模式,抽象工厂模式;
根据产品是具体产品还是具体工厂可分为简单工厂模式和工厂方法模式,根据工厂的抽象程度可分为工厂方法模式和抽象工厂模式。该模式用于封装和管理对象的创建,是一种创建型模式。
其中简单工厂模式对对象创建管理方式最为简单,因为其仅仅简单的对不同类对象的创建进行了一层薄薄的封装。该模式通过向工厂传递类型来指定要创建的对象。
另外两个工厂模式在后续章节记述。
二:结构与实现
1.Factory(工厂):核心部分,负责实现创建所有产品的内部逻辑,工厂类可以被外界直接调用,创建所需对象
2.Product(抽象类产品):工厂类所创建的所有对象的父类,封装了产品对象的公共方法,所有的具体产品为其子类对象
3.ConcreteProduct(具体产品):简单工厂模式的创建目标,所有被创建的对象都是某个具体类的实例。它要实现抽象产品中声明的抽象方法(有关抽象类)
abstract class Product
{
public void MethName()
{
//公共方法的实现
}
public abstract void MethodDiff();
//声明抽象业务方法
}
class ConcreteProductA : Product
{
public override void MethodDiff()
{
//业务方法的实现
}
}
class Factory
{
public static Product GetProduct(string arg)
{
Product product = null;
if(arg.Equals("A")
{
product = new ConcreteProductA();
//init
}
else if(arg.Equals("B"))
{
product = new ConcreteProductB();
//init
}
else
{
....//其他情况
}
return product;
}
}
class Program
{
static void Main(string[] args)
{
Product product;
product = Factory.GetProduct("A");//工厂类创建对象
Product.MethName();
product.MethodDiff();
}
}
三:应用
例子名称:计算器
例子应用模式结构:
用简单工厂模式完成计算器+,-的过程代码:
#include <iostream>
using namespace std;
// 计算法则基类
class Operation
{
public:
virtual ~Operation(){
cout << "virtual ~Operation()" << endl;
}
double num1;
double num2;
virtual double getResult()=0;
};
// 加法
class PlusOperation : public Operation
{
public:
~PlusOperation(){
cout << "~PlusOperation()" << endl;
}
double getResult()
{
double result = 0;
result = num1 + num2;
return result;
}
};
// 减法
class SubOperation : public Operation
{
public:
~SubOperation(){
cout << "~SubOperation()" << endl;
}
double getResult()
{
double result = 0;
result = num1 - num2;
return result;
}
};
// 创建法则的工厂类
class OperationFactory
{
public:
// 工厂类:专们负责法则类的生成,不关心各法则内部的实现;
// 好处:
// 1.新增运算时,不会改动原有法则的代码,即易扩展;
// 2.修改某一运算时,不会影响别的地方的代码,即易维护;
// 3.如果windows界面程序,网页程序想要用这块代码,也可以使用,即易复用;
static Operation* createOperate(string operate)
{
Operation* oper = NULL;
if("+" == operate)
{
oper = new PlusOperation();
}
else if("-" == operate)
{
oper = new SubOperation();
}
return oper;
}
};
int main()
{
cout << "Hello World!" << endl;
Operation* oper = NULL;
oper = OperationFactory::createOperate("+");
oper->num1 = 1;
oper->num2 = 2;
double result = oper->getResult();
cout << result << endl;
delete oper;
return 0;
}
四:优缺点及适用环境
4.1:使用:
不同条件下创建不用实例时。方法是让子类实现工厂接口。
4.2:优缺点:
优点:
(1)工厂类包含必要的逻辑判断,可以决定在什么时候创建哪一个产品的实例。客户端可以免除直接创建产品对象的职责
(2)客户端无需知道所创建具体产品的类名,只需知道参数即可
(3)也可以引入配置文件,在不修改客户端代码的情况下更换和添加新的具体产品类。(这也是我在开始的披萨店里遇到没有的披萨的解决情况)
缺点:
(1)工厂类集中了所有产品的创建逻辑,职责过重,一旦异常,整个系统将受影响
(2)使用简单工厂模式会增加系统中类的个数(引入新的工厂类),增加系统的复杂度和理解难度
(3)系统扩展困难,一旦增加新产品不得不修改工厂逻辑,在产品类型较多时,可能造成逻辑过于复杂
(4)简单工厂模式使用了static工厂方法,造成工厂角色无法形成基于继承的等级结构。
4.3:使用场景
(1)工厂类负责创建对的对象比较少,因为不会造成工厂方法中的业务逻辑过于复杂
(2)客户端只知道传入工厂类的参数,对如何创建对象不关心
4.4:应用实例
需要一辆汽车,直接从工厂里面提货,不用去管这辆车是怎么做出来的。
Hibernate换数据库只需换方言和驱动即可。
简单计算器的实现。