首頁>銀行 > 正文

      一文講透設計模式(C++版) 全球播報

      2023-06-27 23:46:56    出處:阿里開發者

      點擊鏈接閱讀原文,獲取更多技術內容:


      (資料圖)

      本文從設計原則、創建型模式、結構型模式、行為模式四個方向講述C++的設計模式。

      作者 | 恒索

      來源 | 阿里開發者公眾號

      設計原則

      單一職責原則

      定義:單一職責原則[1],所謂職責是指類變化的原因。如果一個類有多于一個的動機被改變,那么這個類就具有多于一個的職責。而單一職責原則就是指一個類或者模塊應該 有且只有一個改變的原因。

      bad case :IPhone類承擔了協議管理(Dial、HangUp)、數據傳送(Chat)。

      good case:

      里式替換原則

      定義:里氏代換原則[2](Liskov Substitution Principle LSP),任何 基類 可以出現的地方, 子類一定可以出現。

      bad case :ToyGun繼承了AbstractGun,但Solider在調用KillEnemy()時會報錯(ToyGun無法KillEnemy),即ToyGun無法完全行使AbstractGun的職責。

      good case: AbstractToy中將聲音、形狀都委托給AbstractGun處理。

      如果子類不能完整地實現父類的方法,或者父類的某些方法在子類中已經發生“畸變”,則建議斷開父子繼承關系,采用依賴、聚集、組合等關系代替。

      依賴倒置原則

      定義:依賴倒置原則[3](Dependence Inversion Principle)是程序要 依賴于抽象接口,不要依賴于具體實現。 簡單的說就是要求對抽象進行編程,不要對實現進行編程,這樣就降低了客戶與實現模塊間的耦合。

      bad case: Driver強依賴于奔馳車。

      good case:

      接口隔離原則

      定義: 接口隔離原則[4],客戶端不應該依賴它不需要的接口。一個類對另一個類的 依賴 應該建立在 最小的接口上 。

      bad case: 星探尋找美女的類圖,其中IpettyGirl過于龐大,容納過多可變的因素。

      good case: 通過拆分接口,提高了靈活性、可維護性。

      迪米特法則

      定義:迪米特法則[5](Law of Demeter)又叫作 最少知識原則 (The Least Knowledge Principle),一個類對于其他類知道的越少越好,就是說一個對象應當對其他對象有盡可能少的了解,只和朋友通信,不和陌生人說話。

      bad case: Teacher要求GroupLeader清點女生的數量,這里Teacher不應該依賴于Gril。

      good case:

      開閉原則

      定義:開閉原則[6],在面向對象編程領域中,規定“軟件中的對象(類,模塊,函數等等)應該對于 擴展是開放 的,但是對于 修改是封閉 的”。

      以一個書店售書類圖為例,當在書店要增加一個打折操作時。

      bad case:修改實現類,在IBook上增加一個方法GetOffPrice() good case:通過擴展實現變化,增加一個子類OffNovelBook

      創建型模式

      工廠方法

      定義一個用于創建對象的接口 Product* CreateProduct() ,讓子類決定實例化哪一個類。工廠方法模式讓類的實例化延遲到子類中進行,從而避免了在父類中創建對象時出現類名稱緊耦合的問題,同時提高了代碼的可擴展性和可維護性。(工廠方法的好處就是 解耦 ,當我們修改了具體的類,對調用方而言完全不用修改)

      class Product {    // 抽象產品public:  virtual void Method() = 0;};class ConcreteProduct1 : public Product {public:  void Method() { cout << \"ConcreteProduct1\" << endl; }};class ConcreteProduct2 : public Product {public:  void Method() { cout << \"ConcreteProduct2\" << endl; }};class Factory {    // 抽象工廠public:  virtual Product* CreateProduct() = 0;};class ConcreteFactory1 : public Factory {public:  Product* CreateProduct() {return new ConcreteProduct1(); }};class ConcreteFactory2 : public Factory {public:  Product* CreateProduct() {return new ConcreteProduct2(); }};int main () {  Factory *factory1 = new ConcreteFactory1();  Factory *factory2 = new ConcreteFactory2();  Product *product1 = factory1->CreateProduct();  Product *product2 = factory2->CreateProduct();  product1->Method();  product2->Method();}

      抽象工廠

      為創建一組相關或相互依賴的對象提供一個接口,而且無須指定他們的具體類。(工廠方法模式針對的是一個產品等級結構;而抽象工廠模式針對的是 多個產品等級結構 。抽象工廠模式主要用來實現生產一系列的產品。)

      class AbstractProductA { public:  virtual ~AbstractProductA(){};  virtual std::string FunctionA() const = 0;};class ProductA1 : public AbstractProductA { public:  std::string FunctionA() const override { return \"The result of the product A1.\"; }};class ProductA2 : public AbstractProductA {  std::string FunctionA() const override { return \"The result of the product A2.\"; }};class AbstractProductB { public:  virtual ~AbstractProductB(){};  virtual std::string FunctionB() const = 0;};class ProductB1 : public AbstractProductB { public:  std::string FunctionB() const override { return \"The result of the product B1.\"; }};class ProductB2 : public AbstractProductB { public:  std::string FunctionB() const override { return \"The result of the product B2.\"; }};class AbstractFactory { public:  virtual AbstractProductA *CreateProductA() const = 0;  virtual AbstractProductB *CreateProductB() const = 0;};class Factory1 : public AbstractFactory { public:  AbstractProductA *CreateProductA() const override { return new ProductA1(); }  AbstractProductB *CreateProductB() const override { return new ProductB1(); }};class Factory2 : public AbstractFactory { public:  AbstractProductA *CreateProductA() const override { return new ProductA2(); }  AbstractProductB *CreateProductB() const override { return new ProductB2(); }};void Client(const AbstractFactory &factory) {  const AbstractProductA *productA = factory.CreateProductA();  const AbstractProductB *productB = factory.CreateProductB();  std::cout << productA->FunctionA() << \"
      \";  std::cout << productB->FunctionB() << \"
      \";  delete productA;  delete productB;}int main() {  Factory1 *f1 = new Factory1();  Client(*f1);  delete f1;  Factory2 *f2 = new Factory2();  Client(*f2);  delete f2;  return 0;}

      生成器/建造者

      將一個復雜對象的構建與它的表示分離,使得同樣的構建過程可以創建不同的表示。(建造者模式關注的是 零件類型 和裝配工藝( 順序 ))

      class Product1{public:    std::vectormParts;    void ListParts()const{        std::cout << \"Product parts: \";        for (size_t i=0;imProduct->mParts.push_back(\"PartA1\"); }    void ProducePartB()const override{ this->mProduct->mParts.push_back(\"PartB1\"); }    void ProducePartC()const override{ this->mProduct->mParts.push_back(\"PartC1\"); }    Product1* GetProduct() {         Product1* result= mProduct;        Reset();        return result;     }};class Director {    Builder* mbuilder;public:    void set_builder(Builder* builder){ mbuilder = builder; }    void BuildMinimalViableProduct(){ mbuilder->ProducePartA(); }    void BuildFullFeaturedProduct(){        mbuilder->ProducePartA();        mbuilder->ProducePartB();        mbuilder->ProducePartC();    }};void ClientCode(Director& director){    ConcreteBuilder1* builder = new ConcreteBuilder1();    director.set_builder(builder);    std::cout << \"Standard basic product:
      \";     director.BuildMinimalViableProduct();    Product1* p= builder->GetProduct();    p->ListParts();    delete p;    std::cout << \"Standard full featured product:
      \";     director.BuildFullFeaturedProduct();    p= builder->GetProduct();    p->ListParts();    delete p;    // Remember, the Builder pattern can be used without a Director class.    std::cout << \"Custom product:
      \";    builder->ProducePartA();    builder->ProducePartC();    p=builder->GetProduct();    p->ListParts();    delete p;    delete builder;}int main(){    Director* director= new Director();    ClientCode(*director);    delete director;    return 0;    }

      原型

      用原型實例指定創建對象的種類,并且通過 拷貝 這些原型創建新的對象。(原型模式實現的是一個Clone 接口,注意是接口,也就是基于 多態的 Clone 虛函數 。)

      class Prototype { protected:  string mPrototypeName;  float mPrototypeField;public:  Prototype() {}  Prototype(string prototypeName)      : mPrototypeName(prototypeName) {  }  virtual ~Prototype() {}  virtual Prototype *Clone() const = 0;  virtual void Function(float prototype_field) {    this->mPrototypeField = prototype_field;    std::cout << \"Call Function from \" << mPrototypeName << \" with field : \" << prototype_field << std::endl;  }};class ConcretePrototype1 : public Prototype {private:  float mConcretePrototypeField;public:  ConcretePrototype1(string prototypeName, float concretePrototypeField)      : Prototype(prototypeName), mConcretePrototypeField(concretePrototypeField) {  }  Prototype *Clone() const override {    return new ConcretePrototype1(*this);  }};class ConcretePrototype2 : public Prototype {private:  float mConcretePrototypeField;public:  ConcretePrototype2(string prototypeName, float concretePrototypeField)      : Prototype(prototypeName), mConcretePrototypeField(concretePrototypeField) {  }  Prototype *Clone() const override {    return new ConcretePrototype2(*this);  }};class PrototypeFactory {private:  std::unordered_map>mPrototypes;public:  PrototypeFactory() {    mPrototypes[Type::PROTOTYPE_1] = new ConcretePrototype1(\"PROTOTYPE_1 \", 50.f);    mPrototypes[Type::PROTOTYPE_2] = new ConcretePrototype2(\"PROTOTYPE_2 \", 60.f);  }  ~PrototypeFactory() {    delete mPrototypes[Type::PROTOTYPE_1];    delete mPrototypes[Type::PROTOTYPE_2];  }  Prototype *CreatePrototype(Type type) {    return mPrototypes[type]->Clone();  }};void Client(PrototypeFactory &prototypeFactory) {  std::cout << \"Let"s create a Prototype 1
      \";  Prototype *prototype = prototypeFactory.CreatePrototype(Type::PROTOTYPE_1);  prototype->Function(90);  delete prototype;  std::cout << \"Let"s create a Prototype 2 
      \";  prototype = prototypeFactory.CreatePrototype(Type::PROTOTYPE_2);  prototype->Function(10);  delete prototype;}int main() {  PrototypeFactory *prototypeFactory = new PrototypeFactory();  Client(*prototypeFactory);  delete prototypeFactory;  return 0;}

      單例

      單例模式是指在整個系統生命周期內,保證 一個類只能產生一個實例 ,確保該類的 唯一性 。

      剩余60%,完整內容請點擊下方鏈接查看:

      阿里云開發者社區,千萬開發者的選擇。百萬精品技術內容、千節免費系統課程、豐富的體驗場景、活躍的社群活動、行業專家分享交流,盡在:

      關鍵詞:

      消費
      產業
      石家莊學院教師團隊獲外研社“教學之星”大賽全國復賽一等獎|世界今日訊 近日,在2023年外研社“教學之星”大賽中,石家莊學院教師呂汝茵、武高
      全球快資訊丨南亞新材跌8.5% 上市即巔峰超募8.7億光大證券保薦 南亞新材跌8 5%上市即巔峰超募8 7億光大證券保薦
      《都市魅影》游戲找小孩 小孩在哪里 都市魅影大叔的孩子在他的家中。可以得知這是一個問句,而且是關于都市
      焦點短訊!甬金股份: 關于子公司完成工商變更登記并換發營業執照的公告 甬金股份:關于子公司完成工商變更登記并換發營業執照的公告
      基金
      久久精品国产亚洲AV无码娇色| 亚洲色图在线播放| 亚洲s码欧洲m码吹潮| 亚洲另类精品xxxx人妖| 亚洲中文字幕乱码熟女在线| 国产精品亚洲片夜色在线| 亚洲久悠悠色悠在线播放| 亚洲乱人伦中文字幕无码| 亚洲精品无码少妇30P| 精品久久亚洲一级α| 亚洲中文字幕无码永久在线 | 图图资源网亚洲综合网站| 亚洲国产成人精品激情| 亚洲女人被黑人巨大进入| 亚洲一区二区三区四区在线观看| 亚洲永久在线观看| 国产精品亚洲二区在线观看| 亚洲综合久久1区2区3区| 日韩亚洲人成网站| 亚洲人成在线影院| 亚洲av成人中文无码专区| 亚洲成在人线av| 亚洲一区二区无码偷拍| 亚洲综合伊人久久大杳蕉| 激情综合亚洲色婷婷五月| 久久亚洲中文字幕精品一区| 亚洲福利电影一区二区?| 亚洲成a人片在线观看国产| 久久精品亚洲综合一品| 亚洲欧美国产欧美色欲| 亚洲国产精彩中文乱码AV| 亚洲色偷偷色噜噜狠狠99| 久久精品国产亚洲综合色| 久久精品国产亚洲av麻豆色欲| 色窝窝亚洲AV网在线观看| 五月天网站亚洲小说| mm1313亚洲精品国产| 亚洲第一AV网站| 亚洲人成电影在线观看青青| 亚洲AV日韩精品一区二区三区| 亚洲日本一区二区三区|