zoukankan      html  css  js  c++  java
  • 设计模式那点事--工厂方法模式

            概念

            工厂方法模式定义了一个用于创建对象的接口让子类决定实例化哪一个类。

    工厂方法使一个类的实例化延迟到其子类。

            组成角色

            在简单工厂模式中,我们把动态创建详细产品类对象放在工厂类。

    因为它负责详细产品对象的分支推断,easy产生高耦合。依据依赖倒转原则。我们在此基础上,把工厂类抽象为一个接口。然后让详细工厂去实现该接口方法。

    组成角色为:

            抽象工厂,详细工厂。抽象产品,详细产品。

            样例

            一个鲜活简单的样例总能让人轻松地理解晦涩的概念。我们来看看一个关于汽车价格的工厂方法模式。

            我们知道,汽车的品牌和质量,决定了它的价格。就像宝马(BMW)。法拉利(Ferrali)和奔驰(Benz)三辆汽车,它们的价格肯定是不一样的。那假设想要知道它的价格的话,能够询问销售人员等等。

    可是在计算机里,我们可不能直接问销售人员啊!

            对于它们来说,尽管各自价格不同,可是获取价格却是一种公共操作。于是,能够创建一个抽象父亲汽车类(Car),声明一个获取价格virtual GetPrice函数的接口

    然后创建三个详细汽车子类:BMW,Ferrali和Benz,分别继承于Car。通过继承关系。每一个子类能够改写父类的GetPrice函数,在client中进行多态调用,获取汽车价格。

            然后再定义一个抽象工厂类PriceFactory。它仅仅提供接口。不实现方法。

    而详细工厂类如BMWFactory通过继承抽象工厂类,承接详细汽车类BMW对象的创建。

            UML



        代码:

    #include <iostream>
    
    using namespace std;
    
    class Car
    {
    public:
    	float m_fPrice;
    	
    public:
    //父类定义为虚函数。实现多态
    	virtual float GetPrice()
    	{
    		return m_fPrice*1;
    	}
    };
    
    class BMW:public Car
    {
    public:
    	float GetPrice()
    	{
    		return m_fPrice*3;
    	}
    };
    
    class Ferrali:public Car
    {
    public:
    	float GetPrice()
    	{
    		return m_fPrice*11;
    	}
    };
    
    class Benz:public Car
    {
    public:
    	float GetPrice()
    	{
    		return m_fPrice*6;
    	}
    };
    
    //抽象类,仅仅提供接口
    class PriceFactory
    {
    public:
    //纯虚函数
    	virtual Car* CreateGetPriceObj() = 0;
    };
    //详细汽车工厂类决定实例化哪一个详细产品类
    class BMWFactory:public PriceFactory
    {
    public:
    	Car* CreateGetPriceObj()
    	{
    		return (new BMW);
    	}
    };
    
    class FerraliFactory:public PriceFactory
    {
    public:
    	Car* CreateGetPriceObj()
    	{
    		return (new Ferrali);
    	}
    };
    
    class BenzFactory:public PriceFactory
    {
    public:
    	Car* CreateGetPriceObj()
    	{
    		return (new Benz);
    	}
    };
    
    int main()
    {
    	float fPrice=0.0;
    	int iTag=0;
    	
    	PriceFactory* priceFactory;
    	Car* car;
    	
    	cout<<"----工厂方法模式開始----"<<endl;
    	cout<<"BMW:1,Ferrali:2,Benz:3"<<endl;
    	cout<<"请输入您想要查询的汽车价格:";
    	cin>>iTag;
    
    //生成详细产品类推断放在client
    	switch (iTag)
    	{
    	case 1:
    		priceFactory = new BMWFactory;
    		break;
    	case 2:
    		priceFactory = new FerraliFactory;
    		break;
    	case 3:
    		priceFactory = new BenzFactory;
    		break;
    	default:
    		priceFactory = new BMWFactory;
    		break;
    	}
    
    //子类指针对象赋给父类,向上转型
    	car = priceFactory->CreateGetPriceObj();
    	car->m_fPrice = 100000.0;
    //由于父类中把GetPrice定义为虚函数,所以可实现多态
    	fPrice = car->GetPrice();
    	
    	delete car;
    	car = NULL;
    	
    	cout<<"价格为:"<<fPrice<<endl;
    	cout<<"----工厂方法模式结束----"<<endl;
    	
    	return 1;
    }

         简单工厂模式与工厂方法模式的差别

         1、工场方法模式是简单工厂方法的衍生;

         2、它们之间都有一个工厂类,可是工厂方法的核心工厂类不再负责产品的创建,它仅仅是作为抽象工厂角色,仅负责提供详细工厂子类必须实现的接口,能够使系统在不改动详细工厂角色的情况下引进新的产品

         3、工厂方法把简单工厂的内部逻辑推断放到了client,对于新加的功能。不用改改工厂类,仅仅要改client即可。这样就不用改动已有的类,更加符合开放-封闭原则(对拓展开放,对改动封闭)。

         应用场景:

         1、第一种情况是对于某个产品。调用者清楚地知道应该使用哪个详细工厂服务,实例化该详细工厂,生产出详细的产品来。

         2、另外一种情况,仅仅是须要一种产品。不是必需知道是哪个工厂生产的,选择工厂决策过程对使用者是透明的。终于选用哪个详细工厂的决定权在生产者一方。它们依据当前系统的情况来实例化一个详细的工厂返回给使用者。


  • 相关阅读:
    宝宝打疫苗
    【小工具】2. 需要对测试用的数据进行MD5加密
    【小工具】1.需要对txt存放的测试数据做去重处理
    【Jenkins】定时构建语法
    【bug】记一个有趣的“bug”
    1.由于测试某个功能,需要生成500W条数据的txt,python代码如下
    开发基于vue前端框架下的系统的UI自动化,记录总结踩的坑
    使用Chrome-headless模式下,截屏不全屏的问题
    Chrome-headless 模式,没有UI界面的自动化UI测试
    【selenium】Webdriver的原理以及工作流程
  • 原文地址:https://www.cnblogs.com/yfceshi/p/6858426.html
Copyright © 2011-2022 走看看