浅述设计模式之单例模式

设计模式C++实现(4)——单例模式 软件领域中的设计模式为开发人员提供了一种使用专家设计经验的有效途径。设计模式中运用了面向对象编程语言的重要特性:封装、继承、多态,真正领悟设计模式的精髓是可能一个漫长的过程,需要大量实践经验的积累。最近看设计模式的书,对于每个模式,用C++写了个小例子,加深一下理解。单例模式 阅读详情

为什么要使用单例?

单例设计模式(Singleton Design Pattern)如果一个类只允许创建一个对象(或者实例),那这个类就是一个单例类,这种设计模式就叫作单例设计模式,简称单例模式。

为什么我们需要单例这种设计模式?它能解决哪些问题?接下来我通过两个实战案例来讲解:

实战案例一:处理资源访问冲突

我们自定义实现了一个往文件中打印日志的 Logger 类。具体的代码实现如下所示:

public class Logger { private FileWriter writer; public Logger() { File file = new File("/Users/mrHandson/log.txt"); writer = new FileWriter(file, true); //true表示追加写入 } public void log(String message) { writer.write(message); } } // Logger类的应用示例: public class UserController { private Logger logger = new Logger(); public void login(String username, String password) { // ...省略业务逻辑代码... logger.log(username + " logined!"); } } public class OrderController { private Logger logger = new Logger(); public void create(OrderVo order) { // ...省略业务逻辑代码... logger.log("Created an order: " + order.toString()); } } 复制代码

所有的日志都写入到同一个文件 /Users/wangzheng/log.txt 中。在 UserController 和 OrderController 中,我们分别创建两个 Logger 对象。在 Web 容器的 Servlet 多线程环境下,如果两个 Servlet 线程同时分别执行 login() 和 create() 两个函数,并且同时写日志到 log.txt 文件中,那就有可能存在日志信息互相覆盖的情况。

为什么会出现互相覆盖呢?我们可以这么类比着理解。在多线程环境下,如果两个线程同时给同一个共享变量加 1,因为共享变量是竞争资源,所以,共享变量最后的结果有可能并不是加了 2,而是只加了 1。同理,这里的 log.txt 文件也是竞争资源,两个线程同时往里面写数据,就有可能存在互相覆盖的情况。

实战案例二:表示全局唯一类

从业务概念上,如果有些数据在系统中只应保存一份,那就比较适合设计为单例类。

比如,配置信息类。在系统中,我们只有一个配置文件,当配置文件被加载到内存之后,以对象的形式存在,也理所应当只有一份。

如何实现一个单例?

要实现一个单例,我们需要关注的点无外乎下面几个: -构造函数需要是 private 访问权限的,这样才能避免外部通过 new 创建实例;

  • 考虑对象创建时的线程安全问题;

  • 考虑是否支持延迟加载;

  • 考虑是否支持延迟加载;

  • 考虑 getInstance() 性能是否高(是否加锁)。

1. 饿汉式

饿汉式的实现方式比较简单。在类加载的时候,instance 静态实例就已经创建并初始化好了,所以,instance 实例的创建过程是线程安全的。不过,这样的实现方式不支持延迟加载(在真正用到 IdGenerator 的时候,再创建实例),从名字中我们也可以看出这一点。具体的代码实现如下所示:

public class IdGenerator { private AtomicLong id = new AtomicLong(0); private static final IdGenerator instance = new IdGenerator(); private IdGenerator() {} public static IdGenerator getInstance() { return instance; } public long getId() { return id.incrementAndGet(); } } 复制代码

因为不支持延迟加载,如果实例占用资源多(比如占用内存多)或初始化耗时长(比如需要加载各种配置文件),提前初始化实例是一种浪费资源的行为。最好的方法应该在用到的时候再去初始化。

如果实例占用资源多,按照 fail-fast 的设计原则(有问题及早暴露),那我们也希望在程序启动时就将这个实例初始化好。如果资源不够,就会在程序启动的时候触发报错(比如 Java 中的 PermGen Space OOM),我们可以立即去修复。这样也能避免在程序运行一段时间后,突然因为初始化这个实例占用资源过多,导致系统崩溃,影响系统的可用性。

2. 懒汉式

懒汉式相对于饿汉式的优势是支持延迟加载。具体的代码实现如下所示:

public class IdGenerator { private AtomicLong id = new AtomicLong(0); private static IdGenerator instance; private IdGenerator() {} public static synchronized IdGenerator getInstance() { if (instance == null) { instance = new IdGenerator(); } return instance; } public long getId() { return id.incrementAndGet(); } } 复制代码

懒汉式的缺点也很明显,我们给 getInstance() 这个方法加了一把大锁(synchronzed),导致这个函数的并发度很低。量化一下的话,并发度是 1,也就相当于串行操作了。而这个函数是在单例使用期间,一直会被调用。如果这个单例类偶尔会被用到,那这种实现方式还可以接受。但是,如果频繁地用到,那频繁加锁、释放锁及并发度低等问题,会导致性能瓶颈,这种实现方式就不可取了。

3. 双重检测

饿汉式不支持延迟加载,懒汉式有性能问题,不支持高并发。那我们再来看一种既支持延迟加载、又支持高并发的单例实现方式,也就是双重检测实现方式。

在这种实现方式中,只要 instance 被创建之后,即便再调用 getInstance() 函数也不会再进入到加锁逻辑中了。所以,这种实现方式解决了懒汉式并发度低的问题。具体的代码实现如下所示:

public class IdGenerator { private AtomicLong id = new AtomicLong(0); private static IdGenerator instance; private IdGenerator() {} public static IdGenerator getInstance() { if (instance == null) { synchronized(IdGenerator.class) { // 此处为类级别的锁 if (instance == null) { instance = new IdGenerator(); } } } return instance; } public long getId() { return id.incrementAndGet(); } } 复制代码

有人说,这种实现方式有些问题。因为指令重排序,可能会导致 IdGenerator 对象被 new 出来,并且赋值给 instance 之后,还没来得及初始化(执行构造函数中的代码逻辑),就被另一个线程使用了。要解决这个问题,我们需要给 instance 成员变量加上 volatile 关键字,禁止指令重排序才行。实际上,只有很低版本的 Java 才会有这个问题。我们现在用的高版本的 Java 已经在 JDK 内部实现中解决了这个问题(解决的方法很简单,只要把对象 new 操作和初始化操作设计为原子操作,就自然能禁止重排序)。关于这点的详细解释,跟特定语言有关,我就不展开讲了,感兴趣的同学可以自行研究一下。

4. 静态内部类

利用 Java 的静态内部类。它有点类似饿汉式,但又能做到了延迟加载。具体是怎么做到的呢?我们先来看它的代码实现。

public class IdGenerator { private AtomicLong id = new AtomicLong(0); private IdGenerator() {} private static class SingletonHolder{ private static final IdGenerator instance = new IdGenerator(); } public static IdGenerator getInstance() { return SingletonHolder.instance; } public long getId() { return id.incrementAndGet(); } } 复制代码

SingletonHolder 是一个静态内部类,当外部类 IdGenerator 被加载的时候,并不会创建 SingletonHolder 实例对象。只有当调用 getInstance() 方法时,SingletonHolder 才会被加载,这个时候才会创建 instance。instance 的唯一性、创建过程的线程安全性,都由 JVM 来保证。所以,这种实现方法既保证了线程安全,又能做到延迟加载。

5. 枚举

这种实现方式通过 Java 枚举类型本身的特性,保证了实例创建的线程安全性和实例的唯一性。具体的代码如下所示:

public enum IdGenerator { INSTANCE; private AtomicLong id = new AtomicLong(0); public long getId() { return id.incrementAndGet(); } } 复制代码

单例存在哪些问题?

在项目中使用单例,都是用它来表示一些全局唯一类,比如配置信息类、连接池类、ID 生成器类。单例模式书写简洁、使用方便,在代码中,我们不需要创建对象,直接通过类似 IdGenerator.getInstance().getId() 这样的方法来调用就可以了。但是,这种使用方法有点类似硬编码(hard code),会带来诸多问题。接下来,我们就具体看看到底有哪些问题:

1. 单例对 OOP 特性的支持不友好

OOP 的四大特性是封装、抽象、继承、多态。单例这种设计模式对于其中的抽象、继承、多态都支持得不好。为什么这么说呢?我们还是通过 IdGenerator 这个例子来讲解。

public class Order { public void create(...) { //... long id = IdGenerator.getInstance().getId(); //... } } public class User { public void create(...) { // ... long id = IdGenerator.getInstance().getId(); //... } } 复制代码

IdGenerator 的使用方式违背了基于接口而非实现的设计原则,也就违背了广义上理解的 OOP 的抽象特性。如果未来某一天,我们希望针对不同的业务采用不同的 ID 生成算法。比如,订单 ID 和用户 ID 采用不同的 ID 生成器来生成。为了应对这个需求变化,我们需要修改所有用到 IdGenerator 类的地方,这样代码的改动就会比较大。

public class Order { public void create(...) { //... long id = IdGenerator.getInstance().getId(); // 需要将上面一行代码,替换为下面一行代码 long id = OrderIdGenerator.getIntance().getId(); //... } } public class User { public void create(...) { // ... long id = IdGenerator.getInstance().getId(); // 需要将上面一行代码,替换为下面一行代码 long id = UserIdGenerator.getIntance().getId(); } } 复制代码

一旦你选择将某个类设计成到单例类,也就意味着放弃了继承和多态这两个强有力的面向对象特性,也就相当于损失了可以应对未来需求变化的扩展性。

2. 单例会隐藏类之间的依赖关系

通过构造函数、参数传递等方式声明的类之间的依赖关系,我们通过查看函数的定义,就能很容易识别出来。但是,单例类不需要显示创建、不需要依赖参数传递,在函数中直接调用就可以了。如果代码比较复杂,这种调用关系就会非常隐蔽。在阅读代码的时候,我们就需要仔细查看每个函数的代码实现,才能知道这个类到底依赖了哪些单例类。

3. 单例对代码的扩展性不友好

我们知道,单例类只能有一个对象实例。如果未来某一天,我们需要在代码中创建两个实例或多个实例,那就要对代码有比较大的改动。你可能会说,会有这样的需求吗?既然单例类大部分情况下都用来表示全局类,怎么会需要两个或者多个实例呢?

实际上,这样的需求并不少见。我们拿数据库连接池来举例解释一下。

在系统设计初期,我们觉得系统中只应该有一个数据库连接池,这样能方便我们控制对数据库连接资源的消耗。所以,我们把数据库连接池类设计成了单例类。但之后我们发现,系统中有些 SQL 语句运行得非常慢。这些 SQL 语句在执行的时候,长时间占用数据库连接资源,导致其他 SQL 请求无法响应。为了解决这个问题,我们希望将慢 SQL 与其他 SQL 隔离开来执行。为了实现这样的目的,我们可以在系统中创建两个数据库连接池,慢 SQL 独享一个数据库连接池,其他 SQL 独享另外一个数据库连接池,这样就能避免慢 SQL 影响到其他 SQL 的执行。

如果我们将数据库连接池设计成单例类,显然就无法适应这样的需求变更,也就是说,单例类在某些情况下会影响代码的扩展性、灵活性。所以,数据库连接池、线程池这类的资源池,最好还是不要设计成单例类。实际上,一些开源的数据库连接池、线程池也确实没有设计成单例类。

4. 单例对代码的可测试性不友好

单例模式的使用会影响到代码的可测试性。如果单例类依赖比较重的外部资源,比如 DB,我们在写单元测试的时候,希望能通过 mock 的方式将它替换掉。而单例类这种硬编码式的使用方式,导致无法实现 mock 替换。

除此之外,如果单例类持有成员变量(比如 IdGenerator 中的 id 成员变量),那它实际上相当于一种全局变量,被所有的代码共享。如果这个全局变量是一个可变全局变量,也就是说,它的成员变量是可以被修改的,那我们在编写单元测试的时候,还需要注意不同测试用例之间,修改了单例类中的同一个成员变量的值,从而导致测试结果互相影响的问题。

5. 单例不支持有参数的构造函数

单例不支持有参数的构造函数,比如我们创建一个连接池的单例对象,我们没法通过参数来指定连接池的大小。

有何替代解决方案?

// 1. 老的使用方式 public demofunction() { //... long id = IdGenerator.getInstance().getId(); //... } // 2. 新的使用方式:依赖注入 public demofunction(IdGenerator idGenerator) { long id = idGenerator.getId(); } // 外部调用demofunction()的时候,传入idGenerator IdGenerator idGenerator = IdGenerator.getInsance(); demofunction(idGenerator); 复制代码

基于新的使用方式,我们将单例生成的对象,作为参数传递给函数(也可以通过构造函数传递给类的成员变量),可以解决单例隐藏类之间依赖关系的问题。不过,对于单例存在的其他问题,比如对 OOP 特性、扩展性、可测性不友好等问题,还是无法解决。

所以,如果要完全解决这些问题,我们可能要从根上,寻找其他方式来实现全局唯一类。实际上,类对象的全局唯一性可以通过多种不同的方式来保证。我们既可以通过单例模式来强制保证,也可以通过工厂模式、IOC 容器(比如 Spring IOC 容器)来保证。

蛋白质组学实战指南 | (八)从数据到洞见:差异蛋白筛选与功能解析全流程 本文系统阐述了蛋白质组学数据分析中,从原始数据质控到差异蛋白筛选与功能解析的全流程。重点介绍了数据质量评估、差异蛋白筛选的统计方法(包括多重检验校正)、功能注释与富集分析,以及蛋白互作网络构建与关键节点识别。最后,为如何将生物信息学洞见转化为实验验证提供了清晰的规划思路,助力研究者完成从数据到生物学知识的闭环。 阅读详情

相关推荐

从爱好者到工程师:如何低成本体验RFSoC ZU47DR?性能实测与避坑指南

本文详细介绍了如何低成本体验赛灵思RFSoC ZU47DR芯片,包括二手开发板选购、租赁服务、精简开发环境搭建等实用方案。通过性能实测与避坑指南,帮助爱好者和工程师在有限预算下充分利用这款集成了ARM处理器和FPGA的高性能芯片,降低开发门槛。

weixin_42525005的博客 221

C++中单例中成员变量的获取最好返回引用

如果单例的成员变量是一个类,并且这个类中又包含了其他成员变量类,在获取该成员变量类时,如果返回的不是成员变量类的引用,可能会导致对象拷贝或移动,引起意外行为或资源管理问题。让我们通过一个示例来说明:假设有一个单例类 Singleton,它有一个成员变量 SomeClass member_;,并且 SomeClass 类中又包含了其他成员变量和资源。

slam、机器人专家 399

python实现语音信号的分帧、加窗、预处理

语音信号实现分帧、加窗、预处理音频文件读取预加重分帧加窗 音频文件读取 librosa是非常强大的python语音信号处理库。 读取音频: 使用语句librosa.load(path, sr=22050, mono=True, offset=0.0, duration=None)读取音频文件,默认的采样率是22050,若要保留音频的原始采样率,使用sr=None。 其中: path:表示音频文件的路径 sr:表示采样率 mono:bool,是布尔类型,表示是否将信号转换为单声道 offset:float,后

weixin_45272908的博客 1万+

设计模式之单例模式

前言 说起设计模式大家肯定都不陌生,经常会听到人说起springbean的单例模式,工厂模式,责任链模式等等,一些耳熟能详的模式满天飞,今天就和大家一起聊聊单例模式的好处和缺点,以及如何选择合适的实现方式。 什么是单例模式 单例设计模式(Singleton Design Pattern)理解起来非常简单。一个类只允许创建一个对象(或者实例),那这个类就是一个单例类,这...

zhaojun20161206的博客 413

Zuken E3.series schematic/cable/Formboard 连载(1)

​ 1987-2001年,CIM-Team公司(德国)推出基于MS-DOS环境下运行的CAD软件DDS-schematic 2002年,在此基础上,推出基于windows环境下运行,应用于电气工程领域的E3.Series 2002-2006年,CIM-Team公司成为Zuken公司(日本)的一家分公司,实现电子电气系统的完整设计平台 覆盖电子、电气原理设计,三维机柜设备布局与配线设计,线缆线束设计及其各类生产报表文档生成的完整设计流程

u010930036的博客 2507

squirrel校园二手交易平台

squirrel校园二手交易平台 (适合寻找SSM项目练手的你。) 项目起源:   期末的课程设计,三人一组,我和两个舍友,一时起兴,决定做一个校园二手交易平台,一开始兴致与激情满满,可是后期时间上的冲突,让我们三个人对于这个项目有点累。   这个项目刚定题两天,BezosLee由于通过了360的网上在线笔试,收到了360公司的免费培训邀请,要去北京的360总部进行培训一周,值得庆...

K.SHI的博客 5万+

成员变量问题

成员变量问题成员变量及其运行机制事例 成员变量及其运行机制 成员变量指的是在类接口部分或类实现部分定义的变量,OC的成员变量的作用都是实例变量,并不支持真正的类变量。 实例变量从该类的实例被创建开始起存在,直到系统完成销毁这个实例,实例变量的作用域与对应实例的生存范围相同。实例变量则可理解为实例成员变量,它作为实例的一个成员,与实例共存亡。 只要实例存在,程序就可以访问该实例的实例变量,在程序中访问该实例变量通过如下语法: 实例->实例变量 事例 #import<Foundation/Found

weixin_51638861的博客 487

MTK Linux DRM分析(八)- KMS drm_crtc.c

CRTC 在 Linux DRM 子系统中是显示控制的核心,负责时序生成、模式设置和管线的调度。理解其工作原理和 API 对于进行底层图形开发、调试显示问题或 simply understanding how your graphics stack works 都至关重要。

iTom1900 1350

单例模式中的唯一实例为什么一定要设置为静态的

单例模式中的唯一实例为什么一定要设置为静态的 这里以懒汉式的单例模式为例 public class Emperor { private Emperor(){} private static Emperor instance; public static Emperor getInstance(){ if(instance==null) instance=new Emperor(); return instance;

qq_36996785的博客 3590

跨境电商产品信息抓取:使用Python爬虫进行市场分析

跨境电商平台是指为不同国家和地区的买卖双方提供在线交易服务的电子商务平台。亚马逊(Amazon):全球最大的电商平台之一,提供丰富的商品种类和全球配送服务。eBay:全球知名的在线拍卖和购物网站,支持个人和企业卖家。速卖通(AliExpress):阿里巴巴旗下的跨境电商平台,主要面向全球消费者提供中国制造的商品。Wish:以移动端为主的跨境电商平台,主打低价商品和个性化推荐。这些平台上的商品数据包括商品名称、价格、销量、用户评价、库存等信息,对于市场分析具有重要价值。

2201_76125261的博客 1235

《使用R包ggtree进行进化树的绘制与美化》

都2023年了,才去使用Y叔早在2018年发表的进化树构建利器——ggtree。刚好最近在做基因家族分析,进化树的构建与美化确实有点麻烦,先前使用MEGA11进行了绘制,但图像简陋,于是导出了nwk文件,准备使用其他软件进行美化。这里,我使用ggtree包进行操作。

沉香best的博客 6898

单例模式

单例模式单例模式 基本概念 使用场景 实现步骤 懒汉式单例模式 饿汉式单例模式 多线程下的单例模式 懒汉式单例模式的多线程改进 关于程序并发机制 总结基本概念  单例模式是一种对象创建型模式,使用单例模式,可以保证为一个类只生成唯一的实例对象。也就是说,在整个程序空间中,该类只存在一个实例对象。在代码上表现为整个程序中只调用一次该类的构造函数。   GoF对单例模式的定义是:保证一个类、只有一个

lzjsqn的专栏 702

第3版•系统集成项目管理工程师(中级) │ 告别迷茫!案例分析高分攻略

🥏第3版•系统集成项目管理工程师(中级) │ 告别迷茫!案例分析高分攻略

✨ 欢迎来到【Seal ^_^ 的优快云博客】!✨ 3871

设计模式实战教程:基于 youngyangyang04/DesignPattern 开源项目

设计模式实战教程:基于 youngyangyang04/DesignPattern 开源项目 本教程旨在全面介绍位于 GitHub 的设计模式开源项目。通过深入浅出的讲解,我们将涵盖项目的核心要素,提供快速上手指南,展示经典应用场景,以及探索其在技术生态中的位置。 1. 项目介绍 设计模式 是软件开发中的一套成熟解决方案,用于解决常见的设计问题并促进代码的可重用性、可维护性和扩展性。此开源项目 D...

gitblog_00568的博客 1058

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

廖雪峰Python教程[完整版]

廖雪峰的python教程整理的,已经排好版了,而且还是完整的,适合小白

C++设计模式 - 单例模式

知识的学习在于点滴记录,坚持不懈;知识的学习要有深度和广度,不能只流于表面,坐井观天;知识要善于总结,不仅能够理解,更知道如何表达! 设计模式概念 设计模式简单来说就是在解决某一类问题场景时,有既定的,优秀的代码框架可以直接使用,与我们自己摸索出来的问题解决之道相比较,有以下优点可取: 代码更易于维护,代码的可读性,复用性,可移植性,健壮性会更好 当软件原有需求有变更或者增加新的需求时,合理...

大秦坑王的专栏 4055

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

设计模式实践教程 - 基于 micooz/DesignPattern 开源项目

设计模式实践教程 - 基于 micooz/DesignPattern 开源项目 项目介绍 该项目由 Github 用户 micooz 维护,是针对软件开发中常见设计模式的实现集合。它旨在提供一个学习和理解各种设计模式的实战平台,涵盖了从单例模式到观察者模式等二十多种经典设计模式。通过此仓库,开发者可以深入学习每种模式的概念、应用场景及其实现细节,助力提升代码质量和可维护性。 项目快速启动 环境要求...

gitblog_00751的博客 819

设计模式-单例模式

设计模式记录学习单例模式是java中最简单的设计模式之一,这种类型的设计模式属于创建类型的一种,它提供了创建对象的最佳方式。就是采取一定的方法保证在整个软件系统中,对某个类只能存在一个对象实例,并且该类只提供了一个取得其对象实例的静态方法。例如Hibernate的sessionFactory 它充当数据存储源代理,并且负责创建Session对象.SessionFactory并不是轻量级,一般情况下,一个项目只需要一个SessionFactory,这时就会用到单例模式单例模式注意事项和细节说明。

qq_41217095的博客 1653

php常用设计模式之单例模式

如果实例的初始化开销大,且不一定每次都使用,选择懒汉式,延迟加载可以节省资源。如果应用对响应速度有要求,且希望在系统启动时就获得实例,则选择饿汉式,它提供了线程安全的同时,也减少了同步处理的开销。接下来,我将通过单例模式分别实现 MySQL、Redis、MongoDB 和 Elasticsearch 的连接管理,展示如何在这些场景中应用单例模式。通过单例模式,我们能够高效地管理 MySQL、Redis、MongoDB 和 Elasticsearch 等资源的连接,实现了资源的合理分配与复用。

qq_38917476的博客 3090

设计模式之单例模式浅入浅出

文章目录浅谈单例模式定义:实现思路:单例的实现:饿汉模式饿汉模式的优缺点懒汉模式懒汉模式的优缺点:双重检查锁模式静态内部类单例模式枚举类实现单例模式破坏单例的方法以及解决方法 浅谈单例模式 ​ 摘要: 单例模式是Java中设计模式最简单的一种,只需要一个类就能实现到哪里模式,但是这模式也不能小看,在开发中会遇见很多的坑。 定义: ​ 单例模式在程序运行中只能实例化一次,建立一个全局唯一的对象,和静...

qq779247257的博客 548

Java设计模式——单例模式

介绍Java设计模式的八种单例模式

m0_62946761的博客 7270

深入解析设计模式之单例模式

单例模式的核心要义在于确保一个类在整个系统运行期间仅有一个实例,并且为系统提供一个全局的访问点来获取这个唯一实例。从数学与逻辑学的角度类比,就如同一个 “有且仅有一个元素的集合”。在 Java 的领域中,单例模式被定义为 “一个类有且仅有一个实例,并且自行实例化向整个系统提供”。这意味着,无论在系统的何处需要使用该类的实例,获取到的都是同一个对象,从而避免了资源的重复创建与浪费,保证了系统中特定资源或功能的唯一性和一致性。

weixin_45969711的博客 1390

DesignPattern设计模式

本文主要介绍了设计模式相关内容。包括软件设计的SOLID原则,设计模式的分类,单例模式的思想与实现,工厂模式的思想与实现,建造者模式的思想与实现,代理模式的思想与实现,责任链模式的思想与实现等内容。供个人学习使用。

专注Java和MySQL领域知识分享 1885

设计模式——单例模式

学习了这么长的时间,设计模式却还是浅尝辄止,而且最近在回顾Vue知识的时候,发现了很多常见的设计模式:观察者啊,单例啊什么的。让我意识到,如果想要去读懂Vue底层的话,设计模式的思想是必不可少的。虽然是在学前端,但是准备通过java来学习设计模式,因为毕竟java是一个强类型的语言,通过java能更直观的去学习设计模式的思想。同时也会尽量去将设计模式通过JavaScript的方式实现出来。字面上来看,就是只有一个实例的模式。简单来说,单例模式就是在整个系统中,保持一个实例,不生成新实例的模式。当然并不是说仅

qq_45670042的博客 1248
上一篇: 当数据变得庞大需要进行重构时,微服务该如何拆分
下一篇: 千字带你了解什么是观察者设计模式
Java_LingFeng
博客等级 码龄4年 505粉丝 259原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值