• 大话设计模式C++版——工厂方法模式


             工厂方法模式是以简单工厂模式为基础的,如果未了解简单工厂模式的同学可先浏览《大话设计模式C++版——简单工厂模式》。在简单工厂模式中,提到过简单工厂模式的缺陷,即违背了开发—封闭原则,其主要原因是由于switch的判断结构的使用,使修改或添加新的对象时需要改动简单工厂类的代码,不符合开放—封闭原则,那么工厂方法模式会在那方面有所改进呢?我们仍以简单工厂模式中加减法计算器为例。

    1、保持简单工厂模式的 IOperation 接口和实现对象(COperation_Add 和 COperation_Dec)

    class IOperation
    {
    public:
    	IOperation() : m_nNuml(0), m_nNumr(0) {}
    	virtual	~IOperation() {}
    	
    	virtual	void	SetNum(int nNuml = 0, int nNumr = 0)
    	{
    		m_nNuml = nNuml;
    		m_nNumr = nNumr;
    	}
    	virtual	int		CalculateResult() = 0;
    	
    protected:
    	int	m_nNuml, m_nNumr;
    };
    
    
    class COperation_Add : public IOperation
    {
    public:
    	int		CalculateResult()
    	{
    		return	m_nNuml + m_nNumr;
    	}
    };
    
    
    class COperation_Dec : public IOperation
    {
    public:
    	int		CalculateResult()
    	{
    		return	m_nNuml - m_nNumr;
    	}
    };


    2、和加减法计算器接口类似,将工厂对象也依赖于抽象接口(和简单工厂模式不同之处)

    class IOperationFactory
    {
    public:
    	virtual	~IOperationFactory() {}
    	
    	virtual	IOperation*	CreateOperation() = 0;
    };
    
    
    class COperationFactory_Add : public	IOperationFactory
    {
    public:
    	IOperation*	CreateOperation()
    	{
    		return	new	COperation_Add();
    	}
    };
    
    
    class COperationFactory_Dec : public	IOperationFactory
    {
    public:
    	IOperation*	CreateOperation()
    	{
    		return	new	COperation_Dec();
    	}
    };


          工厂接口 IOperationFactory 提供一个生产 IOperation 计算对象的接口,然后不同的工厂对象生产不同IOperation 计算对象(加法工厂 COperationFactory_Add 生产 COperation_Add 对象,减法工厂 COperationFactory_Dec 则生产 COperation_Dec对象),即每一个生产对象对应一个工厂类,一个工厂类只生产一种产品,如五粮液只生产白酒,而青岛啤酒则只生产啤酒。

    3、使用工厂方法模式

    void	Test()
    {
    	IOperationFactory*	poIOperationFactory = new COperationFactory_Add();	
    	IOperation*	poIOperation = NULL;
    	
    	if (!poIOperationFactory)
    	{
    		return;
    	}
    
    	poIOperation = poIOperationFactory->CreateOperation();
    	 	
    	if (poIOperation)
    	{
    	 	poIOperation->SetNum(2, 3);
    	 	printf("2 + 3 = %d
    ", poIOperation->CalculateResult());
    	 	
    	 	delete poIOperation;
     	}
    
    	delete	poIOperationFactory;
    }


         工厂方法模式使用和简单工厂模式类似,都是先弄一个工厂对象,然后调用工厂对象接口生产计算器对象,不同的是,简单工厂能根据请求类型生产多种计算器对象,而工厂方法模式的工厂只能是一种,如果要生产其他计算器对象,那就是让五粮液卖啤酒——逼良为娼了,唯一的方法只能是换家工厂来干。

        那么问题来了,如果用户要计算乘法了,简单工厂的方式是在简单工厂类中增加一个switch,同时改动用户调用简单工厂接口的符号,即需要改变2处代码,工厂方法模式则需要新增一个生产乘法计算器的工厂类,同时将 poIOperationFactory 改为该工厂new出的对象,即增加一处代码(乘法工厂类),修改一处代码,实际上还是不完全符合开方—封闭原则,但工厂方法模式的改进之处在于,它将简单工厂类修改switch结构的方式改为增加乘法工厂类了,而增加(扩展)是允许的,所以工厂方法模式虽然也要修改代码,但改动减少,这就是工厂方法模式比简单工厂模式的牛X那么一点点的地方。


    本文为博主原创文章,如需转载请说明转至http://www.cnblogs.com/organic/
  • 相关阅读:
    MySQL数据库:第十六章:sql高级函数
    实战:第十篇:使用Java代码获取Linux系统执行命令后的结果
    实战:第十四章:Springboot集成jsp页面报404四种解决方案
    用户注册登录关键代码
    判断用户是否登录关键代码
    springbootstarteraop
    Could not resolve dependency: npm ERR! peer vue@"^3.0.2" from vuex@4.0.2
    解决:npm\vue.ps1,因为在此系统上禁止运行脚本
    解决跨域请求关键代码
    文件重命名和获取用户关键代码
  • 原文地址:https://www.cnblogs.com/organic/p/5005644.html
Copyright © 2020-2023  润新知