zoukankan      html  css  js  c++  java
  • 【C++设计模式二】C++工厂模式

    (1)定义

    简单工厂模式中,每新增一个具体产品,就需要修改工厂类内部的判断逻辑。为了不修改工厂类,遵循开闭原则,工厂方法模式中不再使用工厂类统一创建所有的具体产品,而是针对不同的产品设计了不同的工厂,每一个工厂只生产特定的产品。
    定义一个用于创建对象的接口,但是让子类决定将哪一个类实例化。工厂方法模式让一个类的实例化延迟到其子类。

    (2)结构

    工厂模式结构如下:

    • 抽象工厂(AbstractFactory):所有生产具体产品的工厂类的基类,提供工厂类的公共方法;
    • 具体工厂(ConcreteFactory):生产具体的产品;
    • 抽象产品(AbstractProduct):所有产品的基类,提供产品类的公共方法;
    • 具体产品(ConcreteProduct):具体的产品类。

    (3)实例

    Factory.h

    #ifndef FACTORY_H
    #define FACTORY_H
    #include <iostream>
    #include <string>
    
    /********************************产品类***********************************/
    //抽象产品类AbstractProduct(并非真正意义上的抽象类,含有纯虚函数才是抽象类)
    class AbstractSportProduct
    {
    public:
    	AbstractSportProduct(){}
    	~AbstractSportProduct(){}
        
    	//虚函数
    	virtual void play(){}
    };
    
    //具体产品类Basketball
    class Basketball :public AbstractSportProduct
    {
    public:
    	Basketball(){}
    	~Basketball(){}
    
    	//具体实现方法
    	void play();
    };
    
    //具体产品类Football
    class Football :public AbstractSportProduct
    {
    public:
    	Football(){}
    	~Football(){}
    
    	//具体实现方法
    	void play();
    };
    
    /********************************工厂类***********************************/
    //抽象工厂类
    class AbstractFactory{
    public:
    	//纯虚函数
    	virtual AbstractSportProduct *getSportProduct() = 0;
    };
    
    //具体工厂类BasketballFactory
    class BasketballFactory:public AbstractFactory
    {
    public:
    	BasketballFactory(){}
    	~BasketballFactory(){}
    
    	AbstractSportProduct *getSportProduct();
    };
    
    //具体工厂类FootballFactory
    class FootballFactory:public AbstractFactory 
    {
    public:
    	FootballFactory(){}
    	~FootballFactory(){}
    
    	AbstractSportProduct *getSportProduct();
    };
    
    #endif // FACTORY_H
    

    Factory.cpp

    #include "Factory.h"
    
    /********************************产品类方法***********************************/
    //Basketball方法
    void Basketball::play(){
    	printf("play Basketball
    ");
    }
    
    //Football方法
    void Football::play(){
    	printf("play Football
    ");
    }
    
    /********************************工厂类方法***********************************/
    //BasketballFactory方法
    AbstractSportProduct *BasketballFactory::getSportProduct()
    {
    	return new Basketball();
    }
    
    //FootballFactory方法
    AbstractSportProduct *FootballFactory::getSportProduct()
    {
    	return new Football();
    }
    

    main.cpp

    #include "Factory.h"
    
    int _tmain(int argc, _TCHAR* argv[])
    {
    	AbstractSportProduct *pro = nullptr;
    	AbstractFactory *fac = nullptr;
    
    	fac = new BasketballFactory();
    	pro = fac->getSportProduct();
    	pro->play();
    
    	fac = new FootballFactory();
    	pro = fac->getSportProduct();
    	pro->play();
        
        return 0;
    }
    

    输出结果:

    (4)总结

    如果想增加棒球(Baseball)类,只需要增加一个棒球工厂(BaseballFacory),然后在客户端代码中修改具体工厂类的类名,而原有的类的代码无需修改。由此可看到,相较简单工厂模式,工厂方法模式更加符合开闭原则。工厂方法是使用频率最高的设计模式之一,是很多开源框架和API类库的核心模式。

    优点:

    • 工厂方法用于创建客户所需产品,同时向客户隐藏某个具体产品类将被实例化的细节,用户只需关心所需产品对应的工厂;
    • 工厂自主决定创建何种产品,并且创建过程封装在具体工厂对象内部,多态性设计是工厂方法模式的关键;
    • 新加入产品时,无需修改原有代码,增强了系统的可扩展性,符合开闭原则。

    缺点:

    • 添加新产品时,需要同时添加新的产品工厂,系统中类的数量成对增加,增加了系统的复杂度,更多的类需要编译和运行,增加了系统的额外开销;
    • 工厂和产品都引入了抽象层,客户端代码中均使用的抽象层,增加了系统的抽象层次和理解难度。

    (z)源码路径

    gitee: https://gitee.com/CogenCG/DesignMode

  • 相关阅读:
    【基于mini2440开发板的交叉编译环境及内核树配置.
    linux 模块编译步骤(原)
    鸟哥的linux私房菜
    ios消息机制
    初学者必学文档:Objective-C语法入门(1)
    oc基础知识
    ios 人魔七七
    Usaco Open09 Gold
    USACO JAN 2012 Bronze
    USACO·2012·Feb Bronze
  • 原文地址:https://www.cnblogs.com/lcgbk/p/13819350.html
Copyright © 2011-2022 走看看