【设计模式】我终于读懂了享元模式。。。

简介: 【设计模式】我终于读懂了享元模式。。。

🧧展示网站项目需求


小型的外包项目,给客户 A 做一个产品展示网站,客户 A 的朋友感觉效果不错,也希望做这样的产品展示网站,但是要求都有些不同:

1)有客户要求以新闻的形式发布

2)有客户人要求以博客的形式发布

3)有客户希望以微信公众号的形式发布


🧧传统方案解决网站展现项目


1)直接复制粘贴一份,然后根据客户不同要求,进行定制修改

2)给每个网站租用一个空间

3)方案设计示意图


7f5a97a8d3174bb594b6a4a161d06eb7.png


🧧传统方案解决网站展现项目-问题分析

需要的网站结构相似度很高,而且都不是高访问量网站,如果分成多个虚拟空间来处理,相当于一个相同网站的实例对象很多,造成服务器的资源浪费

🧧解决思路

整合到一个网站中,共享其相关的代码和数据,对于硬盘、内存、CPU、数据库空间等服务器资源都可以达成共享,减少服务器资源,对于代码来说,由于是一份实例,维护和扩展都更加容易

🧧享元模式基本介绍

1)享元模式(Flyweight Pattern) 也叫 蝇量模式: 运用共享技术有效地支持大量细粒度的对象

2)常用于系统底层开发,解决系统的性能问题。像数据库连接池,里面都是创建好的连接对象,在这些连接对象中有我们需要的则直接拿来用,避免重新创建,如果没有我们需要的,则创建一个

3)享元模式能够解决重复对象的内存浪费的问题,当系统中有大量相似对象,需要缓冲池时。不需总是创建新对象,可以从缓冲池里拿。这样可以降低系统内存,同时提高效率


🧧享元模式经典的应用场景就是池技术了,String 常量池、数据库连接池、缓冲池等等都是享元模式的应用,享元模式是池技术的重要实现方式



c7e456dda59c431ba8ad7e2cb955f9bd.png

享元模式的原理类图



4333b23ecefc4c8ebfa8d291cdd3d77a.png


对类图的说明

对原理图的说明-即(模式的角色及职责)


1)FlyWeight 是抽象的享元角色, 他是产品的抽象类, 同时定义出对象的外部状态和内部状态(后面介绍) 的接口或实现

2)ConcreteFlyWeight 是具体的享元角色,是具体的产品类,实现抽象角色定义相关业务

3)UnSharedConcreteFlyWeight 是不可共享的角色,一般不会出现在享元工厂。

4)FlyWeightFactory 享元工厂类,用于构建一个池容器(集合), 同时提供从池中获取对象方法


🧧内部状态和外部状态


比如围棋、五子棋、跳棋,它们都有大量的棋子对象,围棋和五子棋只有黑白两色,跳棋颜色多一点,所以棋子颜色就是棋子的内部状态;而各个棋子之间的差别就是位置的不同,当我们落子后,落子颜色是定的,但位置是变化的,所以棋子坐标就是棋子的外部状态


1)享元模式提出了两个要求:细粒度和共享对象。这里就涉及到内部状态和外部状态了,即将对象的信息分为两个部分:内部状态和外部状态

2)内部状态指对象共享出来的信息,存储在享元对象内部且不会随环境的改变而改变。

3)外部状态指对象得以依赖的一个标记,是随环境改变而改变的、不可共享的状态。

4)举个例子:围棋理论上有 361 个空位可以放棋子,每盘棋都有可能有两三百个棋子对象产生,因为内存空间有限,一台服务器很难支持更多的玩家玩围棋游戏,如果用享元模式来处理棋子,那么棋子对象就可以减少到只有两个实例(颜色),这样就很好的解决了对象的开销问题


🧧享元模式解决网站展现项目



3462decef20d4e288c5e19fb6f9b5d76.png



WebSite类,定义了最外层的抽象方法


cd58cca314504c439d24fdba3aea0058.png

ConcreteWebSite类,具体网站


80e4403a8e7149029c94cb6371a091d5.png



WebSiteFactory类,网站工厂类,根据需要返回一个网站

d39adfa567c648f785012298185d4d60.png


User类,定义了用户类

d036295fd03847c898c44b1b570f2883.png


Client,客户端,启动类


404e8daed0a744cc85cc3ab41824deb9.png

运行一下看看结果


05f8e620f13a4196bb2f34b6e47c4d2b.png


现在我们debug跟着源码去理解一下

进入getWebSiteCategory方法

8aff5fe1a6df4933a95d4c46407211a1.png


此时的池里面并没有这个type



b37ccae7837241438fe576c4fe0c4eef.png


我们给他创建一个ConcreteWebSite



9c6003b0be4046c688165e2c484ea8b7.png

这个时候我们有一个新闻网站了

75a0a687016242a2a4b3470fa11b4d1f.png


现在给他一个外部状态9fda1c9fbec1440abfedbf52e9f6c7a5.png

1db79703f2d24a799e8f422f7724e254.png


到第二个类型的时候已经有该类型了


7a85e4a153c34e73896c719bf7424c50.png

我们直接返回出去就行了


bc8e6664e99f4e3fbf457cc4903c8592.png



但是我们的使用者不同

934073c0b13f4248b83520f7e2d8c2f1.png


我们现在一共有两个网站,四个使用者


17b99bad8c774728b8b7b157d68886b2.png

但是我们的池的数量还是两个


469df62dee464c09b00da5c445b889bf.png

🧧享元模式在 JDK-Interger 的应用源码分析

1)Integer 中的享元模式

2)代码分析+Debug 源码+说明

3f11b3ede3164c119dc3da493b04b317.png


3f72996a933044d99ad93e809077bab3.png


这里可以理解为 -128 - 127为内部状态

🧧享元模式的注意事项和细节


1)在享元模式这样理解,“享”就表示共享,“元”表示对象

2)系统中有大量对象,这些对象消耗大量内存,并且对象的状态大部分可以外部化时,我们就可以考虑选用享元模式

3)用唯一标识码判断,如果在内存中有,则返回这个唯一标识码所标识的对象,用 HashMap/HashTable 存储

4)享元模式大大减少了对象的创建,降低了程序内存的占用,提高效率

5)享元模式提高了系统的复杂度。需要分离出内部状态和外部状态,而外部状态具有固化特性,不应该随着内部状态的改变而改变,这是我们使用享元模式需要注意的地方.

6)使用享元模式时,注意划分内部状态和外部状态,并且需要有一个工厂类加以控制。

7)享元模式经典的应用场景是需要缓冲池的场景,比如 String 常量池、数据库连接池


资料参考:https://www.bilibili.com/video/BV1G4411c7N4


代码地址:https://gitee.com/WangFuGui-Ma/design-pattern/tree/master/design

相关文章
|
6月前
|
设计模式 存储 Java
23种设计模式,享元模式的概念优缺点以及JAVA代码举例
【4月更文挑战第6天】享元模式(Flyweight Pattern)是一种结构型设计模式,旨在通过共享技术有效地支持大量细粒度对象的重用。这个模式在处理大量对象时非常有用,特别是当这些对象中的许多实例实际上可以共享相同的状态时,从而可以减少内存占用,提高程序效率
97 4
|
6月前
|
设计模式
二十三种设计模式全面解析-组合模式与享元模式的结合应用:实现对象的共享和高效管理
二十三种设计模式全面解析-组合模式与享元模式的结合应用:实现对象的共享和高效管理
|
2月前
|
设计模式 Java
Java设计模式-享元模式(12)
Java设计模式-享元模式(12)
|
3月前
|
设计模式 存储 Java
【十】设计模式~~~结构型模式~~~享元模式(Java)
文章详细介绍了享元模式(Flyweight Pattern),这是一种对象结构型模式,通过共享技术实现大量细粒度对象的重用,区分内部状态和外部状态来减少内存中对象的数量,提高系统性能。通过围棋棋子的设计案例,展示了享元模式的动机、定义、结构、优点、缺点以及适用场景,并探讨了单纯享元模式和复合享元模式以及与其他模式的联用。
【十】设计模式~~~结构型模式~~~享元模式(Java)
|
4月前
|
设计模式 存储 JavaScript
js设计模式【详解】—— 享元模式
js设计模式【详解】—— 享元模式
64 6
|
5月前
|
设计模式 缓存 Java
Java设计模式:享元模式实现高效对象共享与内存优化(十一)
Java设计模式:享元模式实现高效对象共享与内存优化(十一)
|
5月前
|
设计模式 存储 Java
Java设计模式之享元模式详解
Java设计模式之享元模式详解
|
5月前
|
设计模式
享元模式-大话设计模式
享元模式-大话设计模式
|
6月前
|
设计模式 Go
[设计模式 Go实现] 结构型~享元模式
[设计模式 Go实现] 结构型~享元模式
|
6月前
|
设计模式 存储 Java
小谈设计模式(27)—享元模式
小谈设计模式(27)—享元模式

热门文章

最新文章

  • 1
    C++一分钟之-设计模式:工厂模式与抽象工厂
    42
  • 2
    《手把手教你》系列基础篇(九十四)-java+ selenium自动化测试-框架设计基础-POM设计模式实现-下篇(详解教程)
    46
  • 3
    C++一分钟之-C++中的设计模式:单例模式
    53
  • 4
    《手把手教你》系列基础篇(九十三)-java+ selenium自动化测试-框架设计基础-POM设计模式实现-上篇(详解教程)
    37
  • 5
    《手把手教你》系列基础篇(九十二)-java+ selenium自动化测试-框架设计基础-POM设计模式简介(详解教程)
    61
  • 6
    Java面试题:结合设计模式与并发工具包实现高效缓存;多线程与内存管理优化实践;并发框架与设计模式在复杂系统中的应用
    56
  • 7
    Java面试题:设计模式在并发编程中的创新应用,Java内存管理与多线程工具类的综合应用,Java并发工具包与并发框架的创新应用
    40
  • 8
    Java面试题:如何使用设计模式优化多线程环境下的资源管理?Java内存模型与并发工具类的协同工作,描述ForkJoinPool的工作机制,并解释其在并行计算中的优势。如何根据任务特性调整线程池参数
    49
  • 9
    Java面试题:请列举三种常用的设计模式,并分别给出在Java中的应用场景?请分析Java内存管理中的主要问题,并提出相应的优化策略?请简述Java多线程编程中的常见问题,并给出解决方案
    105
  • 10
    Java面试题:设计模式如单例模式、工厂模式、观察者模式等在多线程环境下线程安全问题,Java内存模型定义了线程如何与内存交互,包括原子性、可见性、有序性,并发框架提供了更高层次的并发任务处理能力
    75