zoukankan      html  css  js  c++  java
  • 第8章工厂方法模式

    一 概念

    • 工厂方法模式,定义一个用于创建对象的接口,让子类决定实例化哪一个类,工厂方法使一个类的实例化延迟到其子类

    二 包含的角色

    • 抽象工厂
    • 具体工厂
    • 抽象产品
    • 具体产品

    三 优势

    • 工厂方法模式是对简单工厂模式的稍微的改进。工厂方法模式的用意是定义一个创建产品对象的工厂接口,将实际工作推迟到子类中。
    • 与简单工厂模式相比,制造产品的工厂类不再只有一个,而是每种具体产品类都对应一个生产它的具体工厂类。而这些具体工厂类的共同特征再被提取出来形成一个抽象产品类,这些具体产品类都继承自这个抽象产品类。
    • 当需要增加一种产品的时候,要做的是:增加一种继承自抽象产品的具体产品类,增加一种继承在抽象工厂的具体工厂类,更改客户端。而不需要在简单工厂模式中那样更改工厂内的switch。

    四 简单工厂VS工厂方法

    • 简单工厂模式的最大优点在于工厂类中包含了必要的逻辑判断,根据客户端的选择条件动态实例化相关的类,对于客户端来说,去除了与具体产品的依赖,但是违背了开放-封闭原则

    四 C++代码实现

    • 计算器的例子
    //工厂方法模式
    //计算器的例子
    #include "pch.h"
    #include <iostream>
    using namespace std;
    
    //抽象产品类
    class Operation
    {
    public:
    	double GetA() const
    	{
    		return numberA;
    	}
    	double GetB() const
    	{
    		return numberB;
    	}
    	void SetA(const double number)
    	{
    		numberA = number;
    	}
    	void SetB(const double number)
    	{
    		numberB = number;
    	}
    	virtual double GetResult()
    	{
    		double result = 0.0;
    		return result;
    	}
    
    protected:
    	double numberA;
    	double numberB;
    };
    
    //下面是四个具体的产品类
    class OperationAdd :public Operation
    {
    public:
    	double GetResult()
    	{
    		double result = 0;
    		result = numberA + numberB;
    		return result;
    	}
    };
    
    class OperationSub :public Operation
    {
    public:
    	double GetResult()
    	{
    		double result = 0;
    		result = numberA - numberB;
    		return result;
    	}
    };
    
    class OperationMul :public Operation
    {
    public:
    	double GetResult()
    	{
    		double result = 0;
    		result = numberA * numberB;
    		return result;
    	}
    };
    
    class OperationDiv :public Operation
    {
    public:
    	double GetResult()
    	{
    		double result = 0;
    		if (numberB != 0)
    			result = numberA / numberB;
    		return result;
    	}
    };
    
    //抽象工厂类
    class IFactory
    {
    public:
    	virtual Operation* createOperation()
    	{
    		return new Operation;
    	}
    };
    
    //下面是四个具体工厂类,分别用于产生四个具体产品
    class AddFactory : public IFactory
    {
    public:
    	Operation* createOperation()
    	{
    		oper = new OperationAdd;
    		return oper;
    	}
    	~AddFactory()
    	{
    		if (oper != NULL)
    		{
    			delete oper;
    			oper = NULL;
    		}
    	}
    private:
    	Operation* oper;
    };
    
    class SubFactory : public IFactory
    {
    public:
    	Operation* createOperation()
    	{
    		oper = new OperationSub;
    		return oper;
    	}
    	~SubFactory()
    	{
    		if (oper != NULL)
    		{
    			delete oper;
    			oper = NULL;
    		}
    	}
    private:
    	Operation* oper;
    };
    
    class MulFactory : public IFactory
    {
    public:
    	Operation* createOperation()
    	{
    		oper = new OperationMul;
    		return oper;
    	}
    	~MulFactory()
    	{
    		if (oper != NULL)
    		{
    			delete oper;
    			oper = NULL;
    		}
    	}
    private:
    	Operation* oper;
    };
    
    class DivFactory : public IFactory
    {
    public:
    	Operation* createOperation()
    	{
    		oper = new OperationDiv;
    		return oper;
    	}
    	~DivFactory()
    	{
    		if (oper != NULL)
    		{
    			delete oper;
    			oper = NULL;
    		}
    	}
    private:
    	Operation* oper;
    };
    
    int main()
    {
    	IFactory *af = NULL;
    	af = new SubFactory();
    
    	Operation* oper = af->createOperation();
    	oper->SetA(50);
    	oper->SetB(19);
    	cout << oper->GetResult() << endl;
    }
    
    • 雷锋工厂的例子
    #include "pch.h"
    #include <iostream>
    #include <string>
    using namespace std;
    
    class LeiFeng
    {
    public:
    	virtual void Sweep()
    	{
    		cout << "扫地" << endl;
    	}
    	virtual void Wash()
    	{
    		cout << "洗衣" << endl;
    	}
    	virtual void BuyRice()
    	{
    		cout << "买米" << endl;
    	}
    };
    
    class Undergraduate : public LeiFeng
    {
    public:
    	void Sweep()
    	{
    		cout << "学生-扫地" << endl;
    	}
    	void Wash()
    	{
    		cout << "学生-洗衣" << endl;
    	}
    	void BuyRice()
    	{
    		cout << "学生-买米" << endl;
    	}
    };
    
    class Volunteer : public LeiFeng
    {
    public:
    	void Sweep()
    	{
    		cout << "志愿者-扫地" << endl;
    	}
    	void Wash()
    	{
    		cout << "志愿者-洗衣" << endl;
    	}
    	void BuyRice()
    	{
    		cout << "志愿者-买米" << endl;
    	}
    };
    
    //雷锋工厂
    class IFactory
    {
    public:
    	virtual LeiFeng* CreateLeiFeng()
    	{
    		oper = new LeiFeng;
    		return oper;
    	}
    	~IFactory()
    	{
    		if (oper != NULL)
    		{
    			delete oper;
    			oper = NULL;
    		}
    	}
    private:
    	LeiFeng* oper;
    };
    
    //生成学雷锋的大学生的工厂
    class UndergraduateFactory : public IFactory
    {
    public:
    	LeiFeng* CreateLeiFeng()
    	{
    		return new Undergraduate;
    	}
    };
    
    //生成社区志愿者的工厂
    class VolunteerFactory : public IFactory
    {
    public:
    	LeiFeng* CreateLeiFeng()
    	{
    		return new Volunteer;
    	}
    };
    
    int main()
    {
    	IFactory* factory = new UndergraduateFactory;
    	LeiFeng* student = factory->CreateLeiFeng();
    
    	student->BuyRice();
    	student->Sweep();
    	student->Wash();
    	return 0;
    }
    

    参考资料:
    1 《大话设计模式C++实现-第8章-工厂方法模式》 https://blog.csdn.net/xiqingnian/article/details/40957025

  • 相关阅读:
    Vue.nextTick()的介绍和使用场景
    JS实现数据双向绑定
    JS对象的可枚举属性和不可枚举属性
    JS中对象转数组方法总结
    Vmware虚拟机安装XP系统
    javascript和c#的深度拷贝的一种通用方法
    c# SQLServer导入大批量数据
    PowerDesigner逆向工程,从SQL Server数据库生成Physical Model -----数据源方式
    虚拟机和主机ping不通,SQL Server无法远程连接的解决方法
    c#生成试卷。。。
  • 原文地址:https://www.cnblogs.com/Manual-Linux/p/11112449.html
Copyright © 2011-2022 走看看