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

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

🧧展示网站项目需求


小型的外包项目,给客户 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

相关文章
|
25天前
|
设计模式 存储 Java
23种设计模式,享元模式的概念优缺点以及JAVA代码举例
【4月更文挑战第6天】享元模式(Flyweight Pattern)是一种结构型设计模式,旨在通过共享技术有效地支持大量细粒度对象的重用。这个模式在处理大量对象时非常有用,特别是当这些对象中的许多实例实际上可以共享相同的状态时,从而可以减少内存占用,提高程序效率
35 4
|
7月前
|
设计模式 存储 缓存
结构型设计模式07-享元模式
结构型设计模式07-享元模式
20 0
|
5月前
|
设计模式 存储 安全
二十三种设计模式全面解析-享元模式(Flyweight Pattern)详解:构建高效共享的对象结构
二十三种设计模式全面解析-享元模式(Flyweight Pattern)详解:构建高效共享的对象结构
|
5月前
|
设计模式
二十三种设计模式全面解析-组合模式与享元模式的结合应用:实现对象的共享和高效管理
二十三种设计模式全面解析-组合模式与享元模式的结合应用:实现对象的共享和高效管理
|
7月前
|
设计模式 存储 Java
【设计模式——学习笔记】23种设计模式——享元模式Flyweight(原理讲解+应用场景介绍+案例介绍+Java代码实现)
【设计模式——学习笔记】23种设计模式——享元模式Flyweight(原理讲解+应用场景介绍+案例介绍+Java代码实现)
29 0
|
16天前
|
设计模式 存储 Java
小谈设计模式(27)—享元模式
小谈设计模式(27)—享元模式
|
2月前
|
设计模式 缓存 Java
设计模式之享元模式
设计模式之享元模式
|
2月前
|
设计模式 存储 缓存
【设计模式】享元模式
【设计模式】享元模式
|
4月前
|
设计模式 存储 缓存
聊聊Java设计模式-享元模式
享元(Flyweight)模式:顾名思义就是**被共享的单元**。意图是复用对象,节省内存,提升系统的访问效率。比如在红白机冒险岛游戏中的背景花、草、树木等对象,实际上是可以多次被不同场景所复用共享,也是为什么以前的游戏占用那么小的内存,却让我们感觉地图很大的原因。
17 3
聊聊Java设计模式-享元模式
|
9月前
|
设计模式 存储 缓存
享元模式【Java设计模式】
享元模式【Java设计模式】
31 0
享元模式【Java设计模式】