当前位置: 首页 > news >正文

常见的创建型设计模式( 一 )

设计模式( 一 )

常见的创建型设计模式

1.单例模式 : 确保一个类只有一个实例 , 为整个程序提供一个全局的访问接口。getInstance

实现方式

  • 饿汉式,在调用getInstance 创建实例的时候 ,实例已经存在了 ,不需要我们再次去 new创建。
    优点: 实现简单 , 在多线程的环境下是线程安全的。
class Singleton {public:static Singleton* getInstance() {return singleton.get();   // 返回管理的原始指针}~Singleton() { cout << __FUNCTION__ << endl;  }private:Singleton() { cout << __FUNCTION__ << endl; }Singleton(const Singleton& other) = delete;Singleton& operator =(const Singleton& other) = delete;static unique_ptr< Singleton >singleton;  // 用智能指针来托管这个有生命周期的对象.避免我们手动去释放};unique_ptr< Singleton>Singleton::singleton( new Singleton);
  • 懒汉式,第一次使用的时候, 才初始化实例
    缺点: 不适合多线程环境( 如果要在多线程下使用 ,需要加锁 )
    优点: 节省资源
  // 利用C++11的新特性 线程安全且简单#include <mutex>class Singleton {public:static Singleton* getInstance() {call_once(flag, []() {   // 保存对象只 new 一次singleton.reset(new Singleton);});return singleton.get(); // 返回管理的原始指针}~Singleton() { cout << __FUNCTION__ << endl; }private:Singleton() { cout << __FUNCTION__ << endl; }Singleton(const Singleton& other) = delete;Singleton& operator =(const Singleton& other) = delete;static unique_ptr<Singleton>singleton;static once_flag flag;};unique_ptr< Singleton>Singleton::singleton;once_flag Singleton::flag;// 其他的写法 ,可以参考class Singleton {public:static Singleton* getInstance() {statict Singleton singleton;return &singleton;}private:Singleton() { cout << __FUNCTION__ << endl; }~Singleton() { cout << __FUNCTION__ << endl; }Singleton(const Singleton& other) = delete;Singleton& operator =(const Singleton& other) = delete;};

适用场景 : 线程池 、系统日志、内存池。等等

2.简单工厂模式: 定义一个工厂类 , 用来创建不同类型的对象实例 .
目的: 将对象创建的过程封装在工厂类里面 , 我们只需要调用工厂类的生产方法 ,而不需要关心具体的实现过程.
基本结构

  • 工厂类 —>用于创建对象的实例
  • 产品类 —> 创建对象的父类
  • 具体产品类----> 继承产品类 , 重写父类的virtual 方法.

具体实现方法:

// 产品类
class Animal {
public:Animal() { }; virtual void eat() = 0;virtual void drinking() = 0;virtual ~Animal( ) { }
};// 具体产品类
class Dog :public Animal {
public:Dog() { }virtual ~Dog() { }virtual void eat() { std::cout << "++ Dog eat" << std::endl; }virtual void drinking() { std::cout << "++ Dog drinking" << std::endl; }
};// 具体产品类
class Cat :public Animal {
public:Cat() { }virtual ~Cat() { }virtual void eat() { std::cout << "++ Cat eat" << std::endl; }virtual void drinking() { std::cout << "++ Cat drinking" << std::endl; }
};// 具体产品类
class Beef :public Animal {
public:Beef() { }virtual ~Beef() { }virtual void eat() { std::cout << "++ Beef eat" << std::endl;  }virtual void drinking() { std::cout << "++ Beef drinking" << std::endl;  }
};// 产品类型
enum class AnimalType :char
{Dog,Cat,Beef
};// 工厂类
class Factory {
public:Factory() { };~Factory() { };// 生产Animal* make_animal( AnimalType  type ) {Animal* animal = nullptr;switch ( type ){case AnimalType::Cat:animal = new Cat;break;case AnimalType::Dog:animal = new Dog;break;case AnimalType::Beef:animal = new Beef;break;default:break;}return animal;}
};int main( ) {// 创建一个工厂实例 , 调用生产方法 ,生成我们需要的产品.Factory factory;   Animal* Beef = factory.make_animal(AnimalType::Beef);Beef->drinking();Animal* Dog = factory.make_animal(AnimalType::Dog);Dog->eat();system("pause");return 0;
}

适用场景: 创建对象的逻辑较为简单、对象类型较少。

3.工厂模式: 它定义了一个创建对象的工厂,但由工厂的子类决定生成哪一个产品。
基本结构:

  • 工厂类 —>定义生产产品的接口
  • 具体工厂类—>继承工厂类 , 对生产接口进行具体实现。返回具体的产品实例
  • 产品类—>定义产品的父类
  • 具体产品类 —> 继承产品类 ,实现产品类的具体方法。

具体的实现:

// 产品类
class Animal {
public:Animal() { }; virtual void eat() = 0;virtual void drinking() = 0;virtual ~Animal( ) { }
};// 具体产品类
class Dog :public Animal {
public:Dog() { }virtual ~Dog() { }virtual void eat() { std::cout << "++ Dog eat" << std::endl; }virtual void drinking() { std::cout << "++ Dog drinking" << std::endl; }
};// 具体产品类
class Cat :public Animal {
public:Cat() { }virtual ~Cat() { }virtual void eat() { std::cout << "++ Cat eat" << std::endl; }virtual void drinking() { std::cout << "++ Cat drinking" << std::endl; }
};// 具体产品类
class Beef :public Animal {
public:Beef() { }virtual ~Beef() { }virtual void eat() { std::cout << "++ Beef eat" << std::endl;  }virtual void drinking() { std::cout << "++ Beef drinking" << std::endl;  }
};// 工厂类
class AbstractFactory {
public:AbstractFactory() { };virtual ~AbstractFactory() { };// 生产virtual Animal* make_animal( ) = 0;
};// 具体工厂类
class DogFactory : public AbstractFactory {
public:DogFactory() { }virtual ~DogFactory() { }virtual Animal* make_animal() {return new Dog;}
};// 具体工厂类
class CatFactory : public AbstractFactory {
public:CatFactory() { }virtual ~CatFactory() { }virtual Animal* make_animal() {return new Cat;}
};// 具体工厂类
class BeefFactory : public AbstractFactory {
public:BeefFactory() { }virtual ~BeefFactory() { }virtual Animal* make_animal() {return new Beef;}
};int main( ) {// 创建一个狗的工厂 ,用于生产狗AbstractFactory  *factory_dog = new DogFactory;Animal* dog = factory_dog->make_animal();dog->eat();// 创建一个猫的工厂 ,用于生产猫AbstractFactory* factory_cat = new CatFactory;Animal* cat = factory_cat->make_animal();cat->drinking();system("pause");return 0;
}

工厂模式是对简单工厂模式的优化 , 将生产产品的的过程延申到工厂的子类中进行实现 , 提高程序的可扩展性。

4.抽象工厂模式: 提供一系列创建产品的接口 , 无需指定具体的类.

适用于: 生产的产品结构比较复杂的类, 入电脑 , 汽车( 由很多零部件构成 , 而同一个零部件又有很多类型).

基本结构:

  • 抽象工厂—> 定义创建产品的方法.
  • 具体工厂—> 实现创建产品的方法 , 这些方法会返回一个具体的产品.
  • 抽象产品 —> 为每种产品声明一个接口.
  • 具体产品 —> 实现抽象产品的接口.
  • 客户端 —> 通过抽象工厂和抽象产品来生产产品.

例如: 建造一海贼艘船

|---------------------- --基础版-----------------豪华版----------------旗舰版 |
| 动力系统------------船桨--------------------内燃机----------------核动力 |
| 防御系统------------防空机枪--------------反舰导弹-------------激光炮 |
| 创建材料------------木头--------------------钢铁-------------------合金 |

具体实现:

#include <iostream>
#include <string>// 动力系统抽象类
class AbstractPower {
public:AbstractPower() {  }virtual ~AbstractPower( ) { }virtual std::string getPower() = 0;
};// 船桨动力
class BodyPower : public AbstractPower {
public:BodyPower() { }virtual ~BodyPower() { }virtual std::string getPower() {return std::string("< 船桨>动力系统");}
};// 内燃机
class EnginePower : public AbstractPower {
public:EnginePower() { }virtual ~EnginePower() { }virtual std::string getPower() {return std::string("< 内燃机>动力系统");}
};// 核动力
class EnergyPower : public AbstractPower {
public:EnergyPower() { }virtual ~EnergyPower() { }virtual std::string getPower() {return std::string("< 核能>动力系统");}
};// 防御系统抽象类
class AbstractDefense {
public:AbstractDefense() { }virtual ~AbstractDefense() { }virtual std::string getDefense() = 0;
};// 防空机枪
class Gun : public AbstractDefense {
public:Gun() { }virtual ~Gun() { }virtual std::string getDefense() {return std::string("<防空机枪>防御系统");}
};// 反舰导弹
class Guided : public AbstractDefense {
public:Guided() { }virtual ~Guided() { }virtual std::string getDefense() {return std::string("<防空导弹>防御系统");}
};// 激光炮
class Laser : public AbstractDefense {
public:Laser() { }virtual ~Laser() { }virtual std::string getDefense() {return std::string("<激光炮>防御系统");}
};// 建造材料抽象类
class AbstractMaterials {
public:AbstractMaterials() { }virtual ~AbstractMaterials() { }virtual std::string getMaterials() = 0;
};// 木头
class Wood :public AbstractMaterials {
public:Wood() { }virtual ~Wood() { }virtual std::string getMaterials() {return std::string("<木头>建造");}
};// 钢铁
class Steel :public AbstractMaterials {
public:Steel() { }virtual ~Steel() { }virtual std::string getMaterials() {return std::string("<钢铁>建造");}
};// 合金
class Alloy :public AbstractMaterials {
public:Alloy() { }virtual ~Alloy() { }virtual std::string getMaterials() {return std::string("<合金>建造");}
};// 船
class Shop {
public:Shop(AbstractPower* power, AbstractDefense* defence, AbstractMaterials* materials):power_(power), defence_(defence), materials_( materials ){  }~Shop( ) { delete power_;delete defence_;delete materials_;}std::string getShopInforamtion() {std::string info = power_->getPower() + defence_->getDefense() + materials_->getMaterials();return info;}
private:AbstractPower* power_;         // 动力系统AbstractDefense* defence_;     // 防御系统AbstractMaterials* materials_;  // 建造材料
};// 工厂抽象类
class AbstractFactory {
public:AbstractFactory( ) { }virtual ~AbstractFactory() { }virtual Shop* CreateShop() = 0;
};class BasicShop :public AbstractFactory {
public:BasicShop( ) { }virtual ~BasicShop( ){ }virtual Shop* CreateShop() {Shop* shop = new Shop(new BodyPower, new Gun, new Wood);std::cout << "<基础形>海贼船建造完毕" << std::endl;return shop;}
};// 
class LuxuryShop :public AbstractFactory {
public:LuxuryShop() { }virtual ~LuxuryShop() { }virtual Shop* CreateShop() {Shop* shop = new Shop(new EnginePower, new Guided, new Steel);std::cout << "<豪华型>海贼船建造完毕" << std::endl;return shop;}
};class FlagshipShop :public AbstractFactory {
public:FlagshipShop() { }virtual ~FlagshipShop() { }virtual Shop* CreateShop() {Shop* shop = new Shop( new EnergyPower , new Laser, new Alloy);std::cout << "<旗舰型>海贼船建造完毕" << std::endl;return shop;}
};int main() {AbstractFactory* factory = new BasicShop;Shop *shop = factory->CreateShop();std::cout << shop->getShopInforamtion() << std::endl;return 0;
}

效果演示:

在这里插入图片描述

相关文章:

  • 数据结构之探索“队列”的奥秘
  • vue elementui table给表格中满足条件的每一条记录添加计时器
  • 低代码平台框架:开源选型、实践与应用深度解析
  • C++拷贝构造函数、运算符重载函数、赋值运算符重载函数、前置++和后置++重载等的介绍
  • ThreadLocal的原理
  • 深入浅出简单工厂模式及其在 Spring 框架中的应用
  • 【专业英语 复习】第9章 Privacy, Security,and Ethics
  • 【Flask】学习
  • 丰臣秀吉-读书笔记六
  • 沙奇里再造世界波,容声注定与经典结缘
  • 如何验证证书的合法性
  • MaxWell实时监控Mysql并把数据写入到Kafka主题中
  • Linux下VSCode的安装和基本使用
  • 数组和链表的区别是什么?
  • Pycharm怎么默认终端连接远程服务器
  • JS中 map, filter, some, every, forEach, for in, for of 用法总结
  • 【comparator, comparable】小总结
  • Angular2开发踩坑系列-生产环境编译
  • Hibernate【inverse和cascade属性】知识要点
  • HTTP--网络协议分层,http历史(二)
  • iOS 系统授权开发
  • java正则表式的使用
  • js递归,无限分级树形折叠菜单
  • magento 货币换算
  • Python进阶细节
  • STAR法则
  • 批量截取pdf文件
  • 前端学习笔记之原型——一张图说明`prototype`和`__proto__`的区别
  • 让你成为前端,后端或全栈开发程序员的进阶指南,一门学到老的技术
  • 什么是Javascript函数节流?
  • 使用agvtool更改app version/build
  • 【运维趟坑回忆录 开篇】初入初创, 一脸懵
  • PostgreSQL 快速给指定表每个字段创建索引 - 1
  • #WEB前端(HTML属性)
  • #我与Java虚拟机的故事#连载02:“小蓝”陪伴的日日夜夜
  • (~_~)
  • (CVPRW,2024)可学习的提示:遥感领域小样本语义分割
  • (Java入门)学生管理系统
  • (二)正点原子I.MX6ULL u-boot移植
  • (附源码)c#+winform实现远程开机(广域网可用)
  • (论文阅读笔记)Network planning with deep reinforcement learning
  • (每日持续更新)jdk api之FileReader基础、应用、实战
  • (十)【Jmeter】线程(Threads(Users))之jp@gc - Stepping Thread Group (deprecated)
  • (学习日记)2024.03.25:UCOSIII第二十二节:系统启动流程详解
  • (转)创业家杂志:UCWEB天使第一步
  • .NET 2.0中新增的一些TryGet,TryParse等方法
  • .NET Core引入性能分析引导优化
  • .NET/C# 推荐一个我设计的缓存类型(适合缓存反射等耗性能的操作,附用法)
  • .NET/MSBuild 中的发布路径在哪里呢?如何在扩展编译的时候修改发布路径中的文件呢?
  • .NetCore发布到IIS
  • .net流程开发平台的一些难点(1)
  • [2016.7.test1] T2 偷天换日 [codevs 1163 访问艺术馆(类似)]
  • [bug总结]: Feign调用GET请求找不到请求体实体类
  • [C/C++]数据结构 深入挖掘环形链表问题
  • [C++]:for循环for(int num : nums)