设计模式—— 简单工厂模式(Simple Factory Pattern)
简单工厂模式简单工厂模式1、背景2、定义3、特征4、应用参考简单工厂模式1、背景我开一家披萨店,当客户需要某种披萨并且我这家店里也能做的时候,我就会为其提供所需要的披萨(当然是要钱的哈哈),如果其所需的我这没有,则是另外的情况,后面会谈。这时候,我这家披萨店就可以看做工厂(Factory),而生产出来的披萨被成为产品(Product),披萨的名称则被称为参数,工厂可以根据参数的不同返回不同的产品,
·
简单工厂模式
1、背景
- 我开一家披萨店,当客户需要某种披萨并且我这家店里也能做的时候,我就会为其提供所需要的披萨(当然是要钱的哈哈),如果其所需的我这没有,则是另外的情况,后面会谈。这时候,我这家
披萨店就可以看做工厂(Factory),而生产出来的披萨被成为产品(Product),披萨的名称则被称为参数,工厂可以根据参数的不同返回不同的产品,这就是简单工厂模式。 - 工厂模式有一种非常形象的描述,建立对象的类就如一个工厂,而需要被建立的对象就是一个个产品;在工厂中加工产品,使用产品的人,不用在乎产品是如何生产出来的。从软件开发的角度来说,这样就有效的降低了模块之间的耦合。
2、定义
ProductA、ProductB和ProductC继承自Product虚拟类,Show方法是不同产品的自描述;Factory依赖于ProductA、ProductB和ProductC,Factory根据不同的条件创建不同的Product对象。
1、定义:
- 定义一个工厂类,他可以根据参数的不同返回不同类的实例,被创建的实例通常都具有共同的父类。
- 简单工厂模式中用于被创建实例的方法通常为静态(static)方法,因此简单工厂模式又被成为静态工厂方法(Static Factory Method)
2、组成环节:
- 1、Factory(工厂):核心部分,负责实现创建所有产品的内部逻辑,工厂类可以被外界直接调用,创建所需对象
- 工厂类是整个模式的关键.包含了必要的逻辑判断,根据外界给定的信息,决定究竟应该创建哪个具体类的对象.通过使用工厂类,外界可以从直接创建具体产品对象的尴尬局面摆脱出来,仅仅需要负责“消费”对象就可以了
- 2、Product(抽象类产品):工厂类所创建的所有对象的父类,封装了产品对象的公共方法,所有的具体产品为其子类对象
- 3、ProductA、ProductB…(具体产品):简单工厂模式的创建目标,所有被创建的对象都是某个具体类的实例。它要实现抽象产品中声明的抽象方法
3、特征
- 1、简单工厂模式的核心思想就是:有一个专门的类(工厂类)来负责创建实例的过程。
- 把产品看着是一系列的类的集合,这些类是由某个抽象类或者接口派生出来的一个对象树。而工厂类用来产生一个合适的对象来满足客户的要求。
- 2、如果简单工厂模式所涉及到的具体产品之间没有共同的逻辑,那么我们就可以使用接口来扮演抽象产品的角色;
- 由于对象的创建过程是我们不需要去关心的,而我们注重的是对象的实际操作,所以,我们需要分离对象的创建和操作两部分,如此,方便后期的程序扩展和维护。
- 3、如果具体产品之间有功能的逻辑或,我们就必须把这些共同的东西提取出来,放在一个抽象类中,然后让具体产品继承抽象类。
- 4.在程序中,需要创建的对象很多,导致对象的new操作多且杂时,需要使用简单工厂模式;
缺点:
- 5、工厂类集中了所有实例的创建逻辑,违反了高内聚责任分配原则,将全部创建逻辑集中到了一个工厂类中;它所能创建的类只能是事先考虑到的,如果需要添加新的类,则就需要改变工厂类
- 6、当系统中的具体产品类不断增多时候,可能会出现要求工厂类根据不同条件创建不同实例的需求.这种对条件的判断和对具体产品类型的判断交错在一起,很难避免模块功能的蔓延
场景:
- 1、工厂类负责创建的对象比较少;
- 2、客户只知道传入工厂类的参数,对于如何创建对象(逻辑)不关心;
4、应用
对于一个只拥有加减乘除运算的简单计算器:
- 1、设计一个Operation的父类 —— Product
- 2、构造加减乘除四个类继承父类重写运算函数GetResult。—— ProductA、ProductB…(具体产品)
- 3、定义工厂类中的工厂函数,其根据用户的输入new出相应的对象实例并返回其父类的指针。—— Factory(工厂)
//简单工厂模式的核心是,对于一个父类的多个继承子类,
//工厂对象的工厂函数根据用户输入,自动new出一个子类对象并返回其父类的指针
//这样利用父类的指针执行父类的虚函数,就可以动态绑定子类的重写函数,从而实现多态。
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <memory>
using namespace std;
class Operation
{
private:
double A, B;
public:
double GetA() const { return A; }
double GetB() const { return B; }
void SetA(double x) { A = x; }
void SetB(double y) { B = y; }
double virtual GetResult() { return 0; }
Operation() :A(0), B(0) {}
};
class Add : public Operation
{
public:
double GetResult()
{
return GetA() + GetB();
}
};
class Sub : public Operation
{
public:
double GetResult()
{
return GetA() - GetB();
}
};
class Mul : public Operation
{
public:
double GetResult()
{
return GetA()*GetB();
}
};
class Div : public Operation
{
public:
double GetResult()
{
if (GetB() == 0)
{
throw exception("Error!Division by zero");
}
else
return GetA() / GetB();
}
};
class SimpleFactory
{
public:
static Operation * CreateOpeartor(char ch)
{
Operation * p;
switch (ch)
{
case '+':
p = new Add();
break;
case '-':
p = new Sub();
break;
case '*':
p = new Mul();
break;
case '/':
p = new Div();
break;
}
return p;
}
};
int main(int argc, char *argv[])
{
try
{
double A = 0;
double B = 0;
char ch = '\0';
cin >> A >> ch >> B;
std::shared_ptr<Operation> op(SimpleFactory::CreateOpeartor(ch));
op->SetA(A);
op->SetB(B);
cout << op->GetResult() << endl;
}
catch(exception ex)
{
cout << ex.what() << endl;
}
return 0;
}
参考
1、https://www.cnblogs.com/ygsworld/p/10649491.html、
2、程杰《大话设计模式》
3、https://blog.csdn.net/weiwenlongll/article/details/6918164
4、https://www.cnblogs.com/jostree/p/4251756.html
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
已为社区贡献25条内容
所有评论(0)