23种设计模式——创建型模式

设计模式

文章目录

创建型模式

单例模式 1-小明的购物车

单例模式是⼀种创建型设计模式, 它的核⼼思想是保证⼀个类只有⼀个实例,并提供⼀个全局访问点来访问这个实

例。

  • 只有⼀个实例的意思是,在整个应⽤程序中(进程),只存在该类的⼀个实例对象,⽽不是创建多个相同类型的对象。

  • 全局访问点的意思是,为了让其他类能够获取到这个唯⼀实例,该类提供了⼀个全局访问点(通常是⼀个静态 ⽅法),通过这个⽅法就能获得实例

    #include <iostream>
    #include <unordered_map>
    #include <vector>
    #include<mutex>
    #include<atomic>

    class ShoppingCartManager {
    private:
    std::unordered_map<std::string, int> cart;
    std::vectorstd::string order; // 保持顺序

      // 私有构造函数
      ShoppingCartManager() {}
       
      static std::mutex m_mutex;
      //static ShoppingCartManager* m_cart;
      static std::atomic<ShoppingCartManager*> m_atomic; //使用原子变量将对象指针保存
    

    public:
    // 获取购物车实例
    static ShoppingCartManager* getInstance() {
    ShoppingCartManager* m_cart = m_atomic.load();
    if (m_cart == nullptr) {
    m_mutex.lock();
    m_cart = m_atomic.load();
    if (m_cart == nullptr) {
    m_cart = new ShoppingCartManager;
    m_atomic.store(m_cart); //保存对象指针
    }
    m_mutex.unlock();
    }
    return m_cart;
    }

      // 添加商品
      void addToCart(const std::string& itemName, int quantity) {
          if (cart.find(itemName) == cart.end()) { //如果cart里面没有该货物
              order.push_back(itemName); //注意这里是order,为了使得货物和数量能对齐
          }
          cart[itemName] += quantity;
      }
    
      // 查看商品
      void viewCart() const {
          for (const auto& itemName : order) { //这里按照顺序读取货物,保证有序输出;若只用unordered_map,无法保证有序
              std::cout << itemName << " " << cart.at(itemName) << std::endl;
          }
      }
    

    };

    //ShoppingCartManager* ShoppingCartManager::m_cart = nullptr;
    std::atomic<ShoppingCartManager*> ShoppingCartManager::m_atomic;
    std::mutex ShoppingCartManager::m_mutex;

    int main() {
    std::string itemName;
    int quantity;

      ShoppingCartManager* cart = ShoppingCartManager::getInstance();
    
      while (std::cin >> itemName >> quantity) {
          cart->addToCart(itemName, quantity);
      }
    
      cart->viewCart();
    
      return 0;
    

    }

使用静态局部变量保证多线程下的资源安全

工厂模式 2-积木工厂

⼯⼚⽅法模式也是⼀种创建型设计模式,简单⼯⼚模式只有⼀个⼯⼚类,负责创建所有产品,如果要添加新的产品,通常需要修改⼯⼚类的代码。⽽⼯⼚⽅法模式引⼊了抽象⼯⼚和具体⼯⼚的概念,每个具体⼯⼚只负责创建⼀个具体产品,添加新的产品只需要添加新的⼯⼚类⽽⽆需修改原来的代码,这样就使得产品的⽣产更加灵活,⽀持扩展,符合开闭原则。

⼯⼚⽅法模式分为以下⼏个⻆⾊:

抽象⼯⼚:⼀个接⼝,包含⼀个

  • 抽象的⼯⼚⽅法(⽤于创建产品对象)。

  • 具体⼯⼚:实现抽象⼯⼚接⼝,创建具体的产品。

  • 抽象产品:定义产品的接⼝。

  • 具体产品:实现抽象产品接⼝,是⼯⼚创建的对象。

    // 表驱动 + lambda 表达式

    #include<iostream>
    #include<bits/stdc++.h>

    using namespace std;

    class Shape {
    public:
    virtual void show() = 0;
    };

    class Circle : public Shape {
    public:
    void show() {
    cout << "Circle Block" << endl;
    }
    };

    class Square : public Shape {
    public:
    void show () {
    cout << "Square Block" << endl;
    }
    };

    class ShapeFactory {
    public:
    virtual Shape* produce() = 0;
    };

    class CircleFactory : public ShapeFactory {
    public:
    Shape* produce() {
    return new Circle();
    }
    };

    class SquareFactory : public ShapeFactory {
    public:
    Shape* produce() {
    return new Square();
    }
    };

    unordered_map<string, function<ShapeFactory*()>> m {
    {"Circle", { return new CircleFactory();}},
    {"Square", { return new SquareFactory();}},
    };

    class BlocksFactory {
    public:
    vector<Shape*> blocks;

      void CreateBlocks(string& type, int count) {
          ShapeFactory* sf = m[type]();
          Shape* s = sf -> produce();
          for (int i = 0; i < count; i++) {
              blocks.push_back(s);
          }
      }
    
      void Print() {
          for (const auto& s : blocks) {
              s -> show();
          }
    
      }
    

    };

    int main() {
    int produceTime;
    cin >> produceTime;

      string type;
      int count;
      BlocksFactory* bf = new BlocksFactory();
      for (int i = 0; i < produceTime; i++) {
          cin >> type >> count;
          bf->CreateBlocks(type, count);
      }
      bf->Print();
    
      return 0;
    

    }

抽象⼯⼚模式 3-家具工厂

抽象⼯⼚模式包含多个抽象产品接⼝,多个具体产品类,⼀个抽象⼯⼚接⼝和多个具体⼯⼚,每个具体⼯⼚负责创建⼀组相关的产品。

  • 抽象产品接⼝ AbstractProduct : 定义产品的接⼝,可以定义多个抽象产品接⼝,⽐如说沙发、椅⼦、茶⼏都是抽象产品。

  • 具体产品类 ConcreteProduct : 实现抽象产品接⼝,产品的具体实现,古典⻛格和沙发和现代⻛格的沙发都是具体产品。

  • 抽象⼯⼚接⼝AbstractFactory : 声明⼀组⽤于创建产品的⽅法,每个⽅法对应⼀个产品。

  • 具体⼯⼚类 ConcreteFactory : 实现抽象⼯⼚接⼝,,负责创建⼀组具体产品的对象,在本例中,⽣产古典⻛格的⼯⼚和⽣产现代⻛格的⼯⼚都是具体实例.

    #include <iostream>
    #include <string>
    #include <unordered_map>
    #include <functional>

    using namespace std;

    class Sofa {
    public:
    virtual void info() = 0;
    };

    class ModernSofa : public Sofa {
    public:
    void info() override {
    cout << "modern sofa" << endl;
    };
    };

    class ClassicalSofa : public Sofa {
    public:
    void info() override {
    cout << "classical sofa" << endl;
    };
    };

    class Chair {
    public:
    virtual void info() = 0;
    };

    class ModernChair : public Chair {
    public:
    void info() override {
    cout << "modern chair" << endl;
    };
    };

    class ClassicalChair : public Chair {
    public:
    void info() override {
    cout << "classical chair" << endl;
    };
    };

    class Factory {
    public:
    virtual Sofa *buildSofa() = 0;
    virtual Chair *buildChair() = 0;
    };

    class ModernFactory : public Factory {
    public:
    Sofa *buildSofa() override
    {
    return new ModernSofa();
    }

      Chair *buildChair() override
      {
          return new ModernChair();
      }
    

    };

    class ClassicalFactory : public Factory {
    public:
    Sofa *buildSofa() override
    {
    return new ClassicalSofa();
    }

      Chair *buildChair() override
      {
          return new ClassicalChair();
      }
    

    };

    unordered_map<string, function<Factory*()>> factoryTable {
    {"modern", { return new ModernFactory(); }},
    {"classical", { return new ClassicalFactory(); }}
    };

    int main()
    {
    int loop;
    cin >> loop;

      string type;
      while (loop--)
      {
          cin >> type;
          Factory *f = factoryTable[type]();
          Chair *c = f->buildChair();
          Sofa *s = f->buildSofa();
          c->info();
          s->info();
      }
      
      return 0;
    

    }

建造者模式 4-⾃⾏⻋加⼯

建造者模式(也被成为⽣成器模式),是⼀种创建型设计模式,软件开发过程中有的时候需要创建很复杂的对象,⽽建造者模式的主要思想是将对象的构建过程分为多个步骤,并为每个步骤定义⼀个抽象的接⼝。具体的构建过程由实现了这些接⼝的具体建造者类来完成。同时有⼀个指导者类负责协调建造者的⼯作,按照⼀定的顺序或逻辑来执⾏构建步骤,最终⽣成产品。

  • 产品Product:被构建的复杂对象, 包含多个组成部分。
  • 抽象建造者 Builder : 定义构建产品各个部分的抽象接⼝和⼀个返回复杂产品的⽅法
  • 具体建造者 getResult Concrete Builder :实现抽象建造者接⼝,构建产品的各个组成部分,并提供⼀个⽅法返回最终的产品。
  • 指导者 Director :调⽤具体建造者的⽅法,按照⼀定的顺序或逻辑来构建产品。

使⽤建造者模式有下⾯⼏处优点:

  • 使⽤建造者模式可以将⼀个复杂对象的构建与其表示分离,通过将构建复杂对象的过程抽象出来,可以使客户端代码与具体的构建过程解耦

  • 同样的构建过程可以创建不同的表示,可以有多个具体的建造者(相互独⽴),可以更加灵活地创建不同组合的对象

    #include <iostream>
    #include <string>
    #include <unordered_map>
    #include <functional>

    using namespace std;

    class Sofa {
    public:
    virtual void info() = 0;
    };

    class ModernSofa : public Sofa {
    public:
    void info() override {
    cout << "modern sofa" << endl;
    };
    };

    class ClassicalSofa : public Sofa {
    public:
    void info() override {
    cout << "classical sofa" << endl;
    };
    };

    class Chair {
    public:
    virtual void info() = 0;
    };

    class ModernChair : public Chair {
    public:
    void info() override {
    cout << "modern chair" << endl;
    };
    };

    class ClassicalChair : public Chair {
    public:
    void info() override {
    cout << "classical chair" << endl;
    };
    };

    class Factory {
    public:
    virtual Sofa *buildSofa() = 0;
    virtual Chair *buildChair() = 0;
    };

    class ModernFactory : public Factory {
    public:
    Sofa *buildSofa() override
    {
    return new ModernSofa();
    }

      Chair *buildChair() override
      {
          return new ModernChair();
      }
    

    };

    class ClassicalFactory : public Factory {
    public:
    Sofa *buildSofa() override
    {
    return new ClassicalSofa();
    }

      Chair *buildChair() override
      {
          return new ClassicalChair();
      }
    

    };

    unordered_map<string, function<Factory*()>> factoryTable {
    {"modern", { return new ModernFactory(); }},
    {"classical", { return new ClassicalFactory(); }}
    };

    int main()
    {
    int loop;
    cin >> loop;

      string type;
      while (loop--)
      {
          cin >> type;
          Factory *f = factoryTable[type]();
          Chair *c = f->buildChair();
          Sofa *s = f->buildSofa();
          c->info();
          s->info();
      }
      
      return 0;
    

    }

原型模式 5-矩形原型

如果⼀个对象的创建过程⽐较复杂时(⽐如需要经过⼀系列的计算和资源消耗),那每次创建该对象都需要消耗资源,⽽通过原型模式就可以复制现有的⼀个对象来迅速创建/克隆⼀个新对象,不必关⼼具体的创建细节,可以降低对象创建的成本。
原型模式的基本结构

实现原型模式需要给【原型对象】声明⼀个克隆⽅法,执⾏该⽅法会创建⼀个当前类的新对象,并将原始对象中的成员变量复制到新⽣成的对象中,⽽不必实例化。并且在这个过程中只需要调⽤原型对象的克隆⽅法,⽽⽆需知道原型对象的具体类型。

原型模式包含两个重点模块:

  • 抽象原型接⼝ prototype : 声明⼀个克隆⾃身的⽅法

  • 具体原型类 ConcretePrototype : 实现 clone ⽅法,复制当前对象并返回⼀个新对象。在客户端代码中,可以声明⼀个具体原型类的对象,然后调⽤clone() ⽅法复制原对象⽣成⼀个新的对象

    #include<iostream>
    #include<string>
    using namespace std;

    class Prototype {
    public:
    virtual Prototype* clone() = 0;
    virtual void print() = 0;
    virtual ~Prototype() {}
    };

    class Triangle : public Prototype{
    private:
    string color;
    int width, height;
    public:
    Triangle(const string& color, int width, int height)
    : color(color), width(width), height(height) {}

      Prototype* clone() override {
          return new Triangle(this->color, this->width, this->height);
      }
      
      void print() override {
          cout<<"Color: "<<this->color<<", Width: "<<this->width<<", Height: "<<this->height<<endl;
      }
    

    };

    int main(){
    int n;
    string color;
    int w,h;
    cin >> color >> w >> h;
    cin >> n;
    while(n--){

          Prototype* original = new Triangle(color, w, h);
          Prototype* cloned = original->clone();
          cloned->print();
          delete original;
          delete cloned;
      }
      return 0;
    

    }

相关推荐
蜡笔小新..8 小时前
【设计模式】软件设计原则——开闭原则&里氏替换&单一职责
java·设计模式·开闭原则·单一职责原则
性感博主在线瞎搞10 小时前
【面向对象】设计模式概念和分类
设计模式·面向对象·中级软件设计师·设计方法
lucifer31110 小时前
JavaScript 中的组合模式(十)
javascript·设计模式
lucifer31110 小时前
JavaScript 中的装饰器模式(十一)
javascript·设计模式
蜡笔小新..10 小时前
【设计模式】软件设计原则——依赖倒置&合成复用
设计模式·依赖倒置原则·合成复用原则
刷帅耍帅10 小时前
设计模式-代理模式
设计模式·代理模式
神的孩子都在歌唱18 小时前
行为设计模式 -观察者模式- JAVA
java·观察者模式·设计模式
刷帅耍帅1 天前
设计模式-解释器模式
设计模式·解释器模式
刷帅耍帅1 天前
设计模式-备忘录模式
设计模式·备忘录模式