【3】基于多设计模式下的同步异步日志系统-设计模式

详细介绍设计模式

单例模式

⼀个类只能创建⼀个对象,即单例模式,该设计模式可以保证系统中该类只有⼀个实例,并提供⼀个访问它的全局访问点,该实例被所有程序模块共享。⽐如在某个服务器程序中,该服务器的配置信息存放在⼀个⽂件中,这些配置数据由⼀个单例对象统⼀读取,然后服务进程中的其他对象再通过这个单例对象获取这些配置信息,这种⽅式简化了在复杂环境下的配置管理。

单例模式有两种实现模式:饿汉模式和懒汉模式

饿汉模式

程序启动时就会创建⼀个唯⼀的实例对象。 因为单例对象已经确定, 所以⽐较适⽤于多线程环境中, 多线程获取单例对象不需要加锁, 可以有效的避免资源竞争, 提⾼性能。

// 饿汉模式
template<typename T>
class Singleton {
private:static Singleton _eton;
private:Singleton(){}~Singleton(){}
public:Singleton(const Singleton&) = delete;Singleton& operator=(const Singleton&) = delete;static T& getInstance() {return _eton;}
};
Singleton Singleton::_eton;	

懒汉模式

第⼀次使⽤要使⽤单例对象的时候创建实例对象。如果单例对象构造特别耗时或者耗费济源(加载插件、加载⽹络资源等), 可以选择懒汉模式, 在第⼀次使⽤的时候才创建对象。
这⾥介绍的是《Effective C++》⼀书作者 Scott Meyers 提出的⼀种更加优雅简便的单例模式Meyers’ Singleton in C++。
C++11 Static local variables 特性以确保C++11起,静态变量将能够在满⾜ thread-safe 的前提下唯⼀地被构造和析构

// 懒汉模式
template <typename T> 
class Singleton { 
private:Singleton(){}~Singleton(){}
public: Singleton(const Singleton&) = delete;Singleton& operator=(const Singleton&) = delete;static T& getInstance() { static Singleton _eton;return _eton; } 
};

工厂模式

⼯⼚模式是⼀种创建型设计模式, 它提供了⼀种创建对象的最佳⽅式。在⼯⼚模式中,我们创建对象时不会对上层暴露创建逻辑,⽽是通过使⽤⼀个共同结构来指向新创建的对象,以此实现创建-使⽤的分离。
工厂模式可以分为:简单工厂模式,工厂方法模式,抽象工厂模式。

简单工厂模式

简单⼯⼚模式实现由⼀个⼯⼚对象通过类型决定创建出来指定产品类的实例。假设有个⼯⼚能⽣产出⽔果,当客⼾需要产品的时候明确告知⼯⼚⽣产哪类果,⼯⼚需要接收⽤⼾提供的类别信息,当新增产品的时候,⼯⼚内部去添加新产品的⽣产⽅式。

//简单⼯⼚模式:通过参数控制可以⽣产任何产品
// 优点:简单粗暴,直观易懂。使⽤⼀个⼯⼚⽣产同⼀等级结构下的任意产品
// 缺点:
// 1. 所有东西⽣产在⼀起,产品太多会导致代码量庞⼤
// 2. 开闭原则遵循(开放拓展,关闭修改)的不是太好,要新增产品就必须修改⼯⼚⽅法。
#include <iostream>
#include <string>
#include <memory>
class Fruit {public:Fruit(){}virtual void show() = 0;
};
class Apple : public Fruit {public:Apple() {}virtual void show() {std::cout << "我是⼀个苹果" << std::endl;}
};
class Banana : public Fruit {public:Banana() {}virtual void show() {std::cout << "我是⼀个⾹蕉" << std::endl;}
};
class FruitFactory {public:static std::shared_ptr<Fruit> create(const std::string &name) {if (name == "苹果") {return std::make_shared<Apple>();}else if(name == "⾹蕉") {return std::make_shared<Banana>();}return std::shared_ptr<Fruit>();}
};
int main()
{std::shared_ptr<Fruit> fruit = FruitFactory::create("苹果");fruit->show();fruit = FruitFactory::create("⾹蕉");fruit->show();return 0;
}

这个模式的结构和管理产品对象的⽅式⼗分简单, 但是它的扩展性⾮常差,当我们需要新增产品的时候,就需要去修改⼯⼚类新增⼀个类型的产品创建逻辑,违背了开闭原则。

工厂方法模式

在简单⼯⼚模式下新增多个⼯⼚,多个产品,每个产品对应⼀个⼯⼚。假设现在有
A、B 两种产品,则开两个⼯⼚,⼯⼚ A 负责⽣产产品 A,⼯⼚ B 负责⽣产产品 B,⽤⼾只知道产品
的⼯⼚名,⽽不知道具体的产品信息,⼯⼚不需要再接收客⼾的产品类别,⽽只负责⽣产产品。

#include <iostream>
#include <string>
#include <memory>
//⼯⼚⽅法:定义⼀个创建对象的接⼝,但是由⼦类来决定创建哪种对象,使⽤多个⼯⼚分别⽣产指定
的固定产品
// 优点: 
// 1. 减轻了⼯⼚类的负担,将某类产品的⽣产交给指定的⼯⼚来进⾏
// 2. 开闭原则遵循较好,添加新产品只需要新增产品的⼯⼚即可,不需要修改原先的⼯⼚类
// 缺点:对于某种可以形成⼀组产品族的情况处理较为复杂,需要创建⼤量的⼯⼚类.
class Fruit {public:Fruit(){}virtual void show() = 0;
};
class Apple : public Fruit {public:Apple() {}virtual void show() {std::cout << "我是⼀个苹果" << std::endl;}private:std::string _color;
};
class Banana : public Fruit {public:Banana() {}virtual void show() {std::cout << "我是⼀个⾹蕉" << std::endl;}
};
class FruitFactory {public:virtual std::shared_ptr<Fruit> create() = 0;
};
class AppleFactory : public FruitFactory {public:virtual std::shared_ptr<Fruit> create() {return std::make_shared<Apple>();}
};
class BananaFactory : public FruitFactory {public:virtual std::shared_ptr<Fruit> create() {return std::make_shared<Banana>();}
};
int main()
{std::shared_ptr<FruitFactory> factory(new AppleFactory());fruit = factory->create();fruit->show();factory.reset(new BananaFactory());fruit = factory->create();fruit->show();return 0;
}

⼯⼚⽅法模式每次增加⼀个产品时,都需要增加⼀个具体产品类和⼯⼚类,这会使得系统中类的个数成倍增加,在⼀定程度上增加了系统的耦合度。

抽象工厂模式

⼯⼚⽅法模式通过引⼊⼯⼚等级结构,解决了简单⼯⼚模式中⼯⼚类职责太重的问题,但由于⼯⼚⽅法模式中的每个⼯⼚只⽣产⼀类产品,可能会导致系统中存在⼤量的⼯⼚类,势必会增加系统的开销。此时,我们可以考虑将⼀些相关的产品组成⼀个产品族(位于不同产品等级结构中功能相关联的产品组成的家族),由同⼀个⼯⼚来统⼀⽣产,这就是抽象⼯⼚模式的基本思想。

#include <iostream>
#include <string>
#include <memory>
//抽象⼯⼚:围绕⼀个超级⼯⼚创建其他⼯⼚。每个⽣成的⼯⼚按照⼯⼚模式提供对象。
// 思想:将⼯⼚抽象成两层,抽象⼯⼚ & 具体⼯⼚⼦类, 在⼯⼚⼦类种⽣产不同类型的⼦产品
class Fruit {public:Fruit(){}virtual void show() = 0;
};
class Apple : public Fruit {public:Apple() {}virtual void show() {std::cout << "我是⼀个苹果" << std::endl;}private:std::string _color;
};
class Banana : public Fruit {public:Banana() {}virtual void show() {std::cout << "我是⼀个⾹蕉" << std::endl;}
};
class Animal {public:virtual void voice() = 0;
};
class Lamp: public Animal {public:void voice() { std::cout << "咩咩咩\n"; }
};
class Dog: public Animal {public:void voice() { std::cout << "汪汪汪\n"; }
};
class Factory {public:virtual std::shared_ptr<Fruit> getFruit(const std::string &name) = 0;virtual std::shared_ptr<Animal> getAnimal(const std::string &name) = 0;
};
class FruitFactory : public Factory {public:virtual std::shared_ptr<Animal> getAnimal(const std::string &name) {return std::shared_ptr<Animal>();}virtual std::shared_ptr<Fruit> getFruit(const std::string &name) {if (name == "苹果") {return std::make_shared<Apple>();}else if(name == "⾹蕉") {return std::make_shared<Banana>();}return std::shared_ptr<Fruit>();}
};
class AnimalFactory : public Factory {public:virtual std::shared_ptr<Fruit> getFruit(const std::string &name) {return std::shared_ptr<Fruit>();}virtual std::shared_ptr<Animal> getAnimal(const std::string &name) {if (name == "⼩⽺") {return std::make_shared<Lamp>();}else if(name == "⼩狗") {return std::make_shared<Dog>();}return std::shared_ptr<Animal>();}
};
class FactoryProducer {public:static std::shared_ptr<Factory> getFactory(const std::string &name) {if (name == "动物") {return std::make_shared<AnimalFactory>();}else {return std::make_shared<FruitFactory>();}}
};
int main()
{std::shared_ptr<Factory> fruit_factory = FactoryProducer::getFactory("⽔
果");std::shared_ptr<Fruit> fruit = fruit_factory->getFruit("苹果");fruit->show();fruit = fruit_factory->getFruit("⾹蕉");fruit->show();std::shared_ptr<Factory> animal_factory = FactoryProducer::getFactory("动
物");std::shared_ptr<Animal> animal = animal_factory->getAnimal("⼩⽺");animal->voice();animal = animal_factory->getAnimal("⼩狗");animal->voice();return 0;
}

抽象⼯⼚模式适⽤于⽣产多个⼯⼚系列产品衍⽣的设计模式,增加新的产品等级结构复杂,需要对原有系统进⾏较⼤的修改,甚⾄需要修改抽象层代码,违背了“开闭原则”。

建造者模式

建造者模式是⼀种创建型设计模式, 使⽤多个简单的对象⼀步⼀步构建成⼀个复杂的对象,能够将⼀个复杂的对象的构建与它的表⽰分离,提供⼀种创建对象的最佳⽅式。主要⽤于解决对象的构建过于复杂的问题

建造者模式主要基于四个核⼼类实现:
• 抽象产品类:
• 具体产品类:⼀个具体的产品对象类
• 抽象Builder类:创建⼀个产品对象所需的各个部件的抽象接⼝
• 具体产品的Builder类:实现抽象接⼝,构建各个部件
• 指挥者Director类:统⼀组建过程,提供给调⽤者使⽤,通过指挥者来构造产品

#include<iostream>
#include<string>
#include<memory>class Computer//抽象电脑类
{public:Computer(){}void SetBoard(const std::string& Board){_board=Board;}void SetDisplay(const std::string& Display){_display=Display;}virtual void SetOs()=0;void showParamaters(){std::string param="Computer Paramaters:\n";param+="\tBoard:"+_board+"\n";param+="\tDisplay:"+_display+"\n";param+="\tOs:"+_os+"\n";std::cout<<param<<std::endl;}protected:std::string _board;//主板std::string _display;//显示器std::string _os;//操作系统
};class MacBook:public Computer//具体电脑类
{public:    void SetOs() override{_os="Mac Os x12";}
};class Builder//抽象建造者类
{public:  virtual void buildBoard(const std::string& board)=0;virtual void buildDisplay(const std::string& display)=0;virtual void buildOs()=0;virtual std::shared_ptr<Computer> Build()=0;
};class MacBookBuilder:public Builder//具体建造者类
{public:MacBookBuilder():_computer(new MacBook()){}void buildBoard(const std::string& board){_computer->SetBoard(board);}void buildDisplay(const std::string& display){_computer->SetDisplay(display);}virtual void buildOs(){_computer->SetOs();}std::shared_ptr<Computer> Build(){return _computer;}private:std::shared_ptr<Computer> _computer;//利用多态
};class Director//指挥者,产品必须按照某种顺序来生产
{public:Director(Builder* builder):_builder(builder){}void construct(const std::string& board,const std::string& display){//按顺序建造_builder->buildBoard(board);_builder->buildDisplay(display);_builder->buildOs();}private:std::shared_ptr<Builder> _builder;};int main()
{Builder* builder=new MacBookBuilder();std::unique_ptr<Director> director(new Director(builder));director->construct("英特尔","三星");std::shared_ptr<Computer> computer=builder->Build();computer->showParamaters();return 0;
}

代理模式

代理模式指代理控制对其他对象的访问, 也就是代理对象控制对原对象的引⽤。在某些情况下,⼀个对象不适合或者不能直接被引⽤访问,⽽代理对象可以在客⼾端和⽬标对象之间起到中介的作⽤。
代理模式的结构包括⼀个是真正的你要访问的对象(⽬标类)、⼀个是代理对象。⽬标对象与代理对象实现同⼀个接⼝,先访问代理类再通过代理类访问⽬标对象。

代理模式分为静态代理、动态代理:

静态代理指的是,在编译时就已经确定好了代理类和被代理类的关系。也就是说,在编译时就已经确定了代理类要代理的是哪个被代理类。
动态代理指的是,在运⾏时才动态⽣成代理类,并将其与被代理类绑定。这意味着,在运⾏时才能确定代理类要代理的是哪个被代理类。

以租房为例,房东将房⼦租出去,但是要租房⼦出去,需要发布招租启⽰, 带⼈看房,负责维修,这些⼯作中有些操作并⾮房东能完成,因此房东为了图省事,将房⼦委托给中介进⾏租赁。 代理模式实现:

/*房东要把⼀个房⼦通过中介租出去理解代理模式*/
#include <iostream>
#include <string>
class RentHouse {public:virtual void rentHouse() = 0;
};
/*房东类:将房⼦租出去*/
class Landlord : public RentHouse {public: void rentHouse() {std::cout << "将房⼦租出去\n";}
};
/*中介代理类:对租房⼦进⾏功能加强,实现租房以外的其他功能*/
class Intermediary : public RentHouse {
public:void rentHouse() {std::cout << "发布招租启⽰\n";std::cout << "带⼈看房\n";_landlord.rentHouse();std::cout << "负责租后维修\n";}private:Landlord _landlord;
};
int main()
{Intermediary intermediary;intermediary.rentHouse();return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/195912.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Redis Desktop Manager for Mac:高效管理Redis数据的必备工具

Redis是一种快速、可扩展的内存数据库&#xff0c;被广泛应用于缓存、消息队列和实时分析等领域。而Redis Desktop Manager for Mac作为一款专为Mac用户设计的Redis桌面管理工具&#xff0c;为用户提供了高效便捷的方式来管理和操作Redis数据。 首先&#xff0c;Redis Desktop…

【已解决】xxljob连接报错HTTP 302(HTTP 401账号或密码错误)

目录 问题现象&#xff1a; 问题分析&#xff1a; 1、密码中的特殊字符。 2、密码长度问题。 解决方法&#xff1a; 拓展&#xff1a; 问题现象&#xff1a; 今天在生产环境使用xxljob任务调度来创建并执行任务时&#xff0c;出现了程序报错&#xff1a; 通过查询xxljob日志…

降本增笑?滴滴史上最严重服务故障,裁员真不能裁测试

2023 年 11 月 27 日晚间&#xff0c;滴滴因系统故障导致 App 服务异常&#xff0c;不显示定位且无法打车。11 月 27 日晚&#xff0c;滴滴出行进行了回复&#xff1a;非常抱歉&#xff0c;由于系统故障。 2023 年 11 月 28 日早间&#xff0c;滴滴出行消息称&#xff0c;网约…

Spring AOP 概念及其使用

目录 AOP概述 什么是AOP&#xff1f; 什么是Spring AOP ? Spring AOP 快速入门 1.引⼊ AOP 依赖 2.编写AOP程序 Spring AOP 核心概念 1.切点 2.连接点 3.通知 4.切面 通知类型 注意事项: PointCut&#xff08;定义切点&#xff09; 切面优先级 Order 切点表达…

Java中的Future源码讲解

JAVA Future源码解析 文章目录 JAVA Future源码解析前言一、传统异步实现的弊端二、what is Future ?2.1 Future的基本概念2.2Future 接口方法解析2.2.1 取消任务执行cancel2.2.2 检索任务是否被取消 isCancelled2.2.3 检索任务是否完成 isDone2.2.3 检索任务计算结果 get 三、…

Windows server 2019 域环境部署

环境准备 准备3台服务器&#xff0c;配置都是8g2核&#xff0c;50g硬盘&#xff0c;操作系统版本Windows Server 2019 Datacenter 域服务器&#xff1a;adc&#xff0c;192.168.56.120服务器1&#xff1a;server1:&#xff0c;192.168.56.121服务器2&#xff1a;server2&…

新媒体营销教学模拟实训平台解决方案

一、背景与目标 随着新媒体的快速发展&#xff0c;营销人才需求旺盛&#xff0c;而具备新媒体营销能力的人才供给却相对不足。为了解决这一矛盾&#xff0c;本方案旨在构建一个新媒体营销教学模拟实训平台&#xff0c;帮助学生掌握新媒体营销的实际操作技能&#xff0c;提高就…

Python 3 使用 write()、writelines() 函数写入文件

1 使用 write() 函数&#xff0c;将字符串&#xff08;或字节串&#xff0c;仅适用写入二进制文件中&#xff09;写入文件中。 with open(example.txt,w,encodingutf-8) as f:f.write(春夜喜雨\n)f.write(杜甫 [唐代]\n)f.write(好雨知时节&#xff0c;当春乃发生。\n)f.write(…

windows彻底卸载VMware虚拟机

右键停止这些服务 在任务管理器中也结束vmware 在控制面板中卸载 找到注册表 然后在【software】目录下找到【VMware&#xff0c;Inc】&#xff0c;然后选中右键删除&#xff1b; 确保C盘中也没了

关于工业级交换机的分类,你知道多少?

工业级交换机是指专为工业控制领域设计的以太网交换设备。工业级交换机具备电信级的性能特征&#xff0c;能够在恶劣的工作环境下持久耐用。我们的产品系列非常广泛&#xff0c;可以灵活配置各种不同类型的端口&#xff0c;以满足工业领域的多样化使用需求。该产品具有宽温设计…

Oracle ADRCI工具使用说明

1.ADRCI介绍 ADRCI是一个命令行工具&#xff0c;是Oracle 11g中引入的故障可诊断性架构的一部分。 ADRCI可以完成以下&#xff1a; 查看自动诊断信息库&#xff08;ADR&#xff09;中的诊断数据。 查看Health Monitor报告。 将事件和问题信息打包到zip文件中以传输到Oracle Su…

2023年文章生成器推荐

2023年即将结束&#xff0c;今年可以说是大语言模型独领风骚的一年&#xff0c;对于内容创作来说&#xff0c;文章生成类的工具也发生了变化。今天给大伙介绍一些超赞的免费文章生成器&#xff0c;让你在内容创作的路上事半功倍。有了这些神奇的工具&#xff0c;你将能够轻松应…

如何使用内网穿透工具实现公网访问GeoServe Web管理界面

文章目录 前言1.安装GeoServer2. windows 安装 cpolar3. 创建公网访问地址4. 公网访问Geo Servcer服务5. 固定公网HTTP地址6. 结语 前言 GeoServer是OGC Web服务器规范的J2EE实现&#xff0c;利用GeoServer可以方便地发布地图数据&#xff0c;允许用户对要素数据进行更新、删除…

深搜DFS 洛谷 P1706 全排列问题

深度优先搜索DFS&#xff08;第一讲&#xff09;&#xff1a;全排列问题

多波束EM2040D甲板单元更换CPU主板记录

前段时间多波束EM2040D甲板单元的CPU主板到货了。趁着船刚好靠港避风&#xff0c;我们带着这块主板去替换之前借来EM2040C的CPU主板。 1、CF卡替换问题 老主板有个CF卡&#xff0c;见下图。最好的解决方法就是将老CF卡替换新CPU主板上的新CF卡&#xff0c;因为这样改动最小。…

AI大模型专题:北京市人工智能行业大模型创新应用白皮书

今天分享的是人工智能系列深度研究报告&#xff1a;《AI大模型专题&#xff1a;北京市人工智能行业大模型创新应用白皮书》。 &#xff08;报告出品方&#xff1a;北京市科学技术委员会、中关村科技园区管理委员会&#xff09; 报告共计&#xff1a;72页 海量/完整电子版/报…

TI radar_toolbox中的文档说明

分享ti雷达工具箱中的文档&#xff0c;如下图所示 其中software_guides中内容如下 using_uniflash_with_mmwave.html&#xff1a;使用Uniflash烧录bin文件using_ccs_debug.html&#xff1a;使用CCS连接EVM板进行debugUnderstanding_UART_Data_Output_Format.html&#xff1a;输…

Linux认证 | 国内常见的Linux认证有哪些

国内常见的linux认证有哪些&#xff1f; 许多打算从事或者正在从事IT事业的朋友&#xff0c;都对linux认证非常感兴趣&#xff0c;毕竟Linux作为目前世界上最受认可的网络技术认证之一&#xff0c;一直深受IT行业的青睐。 考取Linux认证&#xff0c;能够作为你进入行业的敲门…

CUDA简介——CUDA内存模式

1. 引言 前序博客&#xff1a; CUDA简介——基本概念CUDA简介——编程模式CUDA简介——For循环并行化CUDA简介——Grid和Block内Thread索引 CUDA内存模式&#xff0c;采用分层设计&#xff0c;是CUDA程序与正常C程序的最大不同之处&#xff1a; Thread-Memory Correspondenc…