淺談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;
    }

  工廠方法很簡單,常常做爲一種標準的建立對象的方法。可是缺點就是可能僅僅是爲了改變產品類,就可能須要建立一個新的類,也就是說當被實例化的類根本不發生變化或當實例化出如今子類能夠很容易重定義的操做中,從新建立一個工廠類就顯得太浪費了。

版權全部,歡迎轉載,轉載請註明出處。

相關文章
相關標籤/搜索