浅谈C++设计模式之工厂方法(Factory Method)

  为何要用设计模式?根本缘由是为了代码复用,增长可维护性。编程

  面向对象设计坚持的原则:开闭原则(Open Closed Principle,OCP)、里氏代换原则(Liskov Substitution Principle,LSP)、依赖倒转原则(Dependency Inversion Principle,DIP)、接口隔离原则(Interface Segregation Principle,ISP)、合成/聚合复用原则(Composite/Aggregate Reuse Principle,CARP)、最小知识原则(Principle of Least Knowledge,PLK,也叫迪米特法则)设计模式

  • 开闭原则:模块应该对扩展开放,而对修改关闭。也就是说,在不修改原来的代码的前提下进行扩展。
  • 里氏代换原则:若是调用的是父类的话,那么换成子类也彻底没有问题。
  • 依赖倒转原则:尽可能针对接口编程,而不是针对实现编程。经过抽象父类的指针来调用子类的实现。
  • 接口隔离原则:每一个接口应该只有一种角色,多个角色应该用多个接口来实现。
  • 合成/聚合复用:在新的对象中尽可能使用已有的对象,使新对象向这些对象委派来达到复用已有功能的目的,而不是经过继承来实现。
  • 最少知识原则:一个对象应对其它对象有尽量少的了解。

  上述的这些原则也正是体现了OOP高内聚、低耦合的基本原则,最终目的都是为了代码复用,增长可维护性。设计模式就是本着这些原则来进行OOP设计的一些方法。函数

  设计模式开篇先来介绍工厂方法(Factory Method)模式ui

  对象建立型模式的一种。工厂方法是定义一个用于建立对象的接口,让子类决定实例化哪个类,让一个类的实例化延迟到它的子类中。spa

  • 客户Client
  • 工厂接口Creator
  • 工厂实现类ConcreteCreatorP1和ConcreteCreatorP2
  • 产品接口Product
  • 产品实现类ConcreteProductP1和ConcreteProductP2

  上面是工厂方法模式的类图。设计

  首先咱们有两个产品ProductP1和ProductP2,咱们如今要生产这两个产品,这两个产品特征以下:指针

  (1) start(); 启动code

  (2) execute(); 运行对象

  (3) quit(); 退出blog

  只是启动过程不一样,运行过程不一样,退出也不一样。

那么工厂方法模式是如何实现获得这两个产品的对象的呢??经过上面的类图其实咱们就能够大概知道了,工厂方法大体实现过程。有几个产品,就对应着有几个工厂,每一个工厂负责生产对应的产品。全部工厂都实现了同一个工厂接口Creator。而全部的产品也都实现了同一个产品的接口Product。

  • Product(定义工厂方法所建立的对象的接口,也就是产品的接口)
    • class Product{
          Product(){};
          ~Product(){};
          virtual void start()=0;
          virtual void execute()=0;
          virtual void quit()=0;
      };
  • ConcreteProduct(实现Product接口,也就是每一个产品具体的实现方法,这里有两个产品ConcreteProductP1和ConcreteProductP2)
    • /**************************产品1*******************************/
      class
      ConcreteProductP1:public Product{ ConcreteProductP1(){}; ~ConcreteProductP1(){}; void start(); void execute(); void quit(); }; ConcreteProductP1::start(){ cout<<"<<----------P1 启动---------->>"<<endl; } ConcreteProductP1::execute(){ cout<<"<<----------P1 执行---------->>"<<endl; } ConcreteProductP1::quit(){ cout<<"<<----------P1 退出---------->>"<<endl; } /*************************产品2********************************/ class ConcreteProductP2:public Product{ ConcreteProductP2(){}; ~ConcreteProductP2(){}; void start(); void execute(); void quit(); }; ConcreteProductP2::start(){ cout<<"<<----------P2 启动---------->>"<<endl; } ConcreteProductP2::execute(){ cout<<"<<----------P2 执行---------->>"<<endl; } ConcreteProductP2::quit(){ cout<<"<<----------P2 退出---------->>"<<endl; }
  • Creator(声明工厂方法,该方法返回一个Product类型的对象;Creator也能够定义一个工厂方法的缺省实现,它返回一个缺省的ConcreteProduct对象,能够调用工厂方法以建立一个Product对象)

    class Creator{
    public:
        Creator(){};
        ~Creator(){};
        virtual Product* createProduct()=0;
    };

     

  • ConcreteCreator(重定义工厂方法以返回一个ConcreteProduct实例,这里有两个工厂实现类,各自对应上面的两个产品)
    • /*************************工厂1生成产品1**************************/
      class ConcreteCreatorP1:public Creator{
      public:
          ConcreteCreatorP1(){};
          ~ConcreteCreatorP1(){};
          Product* createProduct();
      };
      Product* ConcreteCreatorP1::createProduct(){
          return new ConcreteProductP1();
      }
      
      /*************************工厂2生成产品2**************************/
      class ConcreteCreatorP2:public Creator{
      public:
          ConcreteCreatorP2(){};
          ~ConcreteCreator()P2{};
          Product* createProduct();
      };
      Product* ConcreteCreatorP2::createProduct(){
          return new ConcreteProductP2();
      }
  • Client (这里使用的是main函数)
  • int main(){
        Creator *factory = new ConcreteCreatorP1();
        Product *p1 = factory.createProduct();
        p1.start();        //p1是这样启动的
        p1.execute();    //p1是这样运行的
        p1.quit();        //p1是这样结束的
        
        Creator *factory = new ConcreteCreatorP2();
        Product *p2 = factory.createProduct();
        p2.start();        //p2是这样启动的
        p2.execute();     //p2是这样运行的
        p2.quit();         //p2是这样结束的
        
        return 0;
    }

  工厂方法很简单,常常做为一种标准的建立对象的方法。可是缺点就是可能仅仅是为了改变产品类,就可能须要建立一个新的类,也就是说当被实例化的类根本不发生变化或当实例化出如今子类能够很容易重定义的操做中,从新建立一个工厂类就显得太浪费了。

版权全部,欢迎转载,转载请注明出处。

相关文章
相关标签/搜索