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

设计模式使用场景实现示例及优缺点(结构型模式——享元模式)

结构型模式

享元模式(Flyweight Pattern)

享元模式,作为软件设计模式中的一员,其核心目标在于通过共享来有效地支持大量细粒度对象的使用。在内存使用优化方面,享元模式提供了一种极为高效的路径,尤其在处理大量对象且这些对象中多数属性相同的情况下表现得尤为突出。

享元模式的基本概念与应用

享元模式基于一个简单的理念:分离变与不变,共享不变,独立变化。具体到实现上,享元模式通常涉及到两个主要的组成部分——享元对象和享元工厂。享元对象中包含的状态可以分为内部状态和外部状态,其中内部状态是可以共享的不变状态,而外部状态则由具体的使用场景决定,不能共享。

内部状态(Intrinsic State):如字符代码的字体、大小等属性,这些属性对于同种类型的对象来说是共有的。

外部状态(Extrinsic State):如字符在文档中的位置,这些状态根据具体的使用场景会有所不同。

使用享元模式的典型场景包括处理大量相似对象时,这些对象由于其数量或复杂度会消耗大量内存资源。例如,在文本编辑器中,每个字符可以是一个对象;而字符的字体、大小可以是内部状态,字符的位置和颜色可以是外部状态。

适用场景

  1. 大量对象

    • 当应用程序使用了大量的对象,且这些对象因为数量巨大而造成很高的内存开销时。
  2. 可重复使用对象的状态

    • 对象的大多数状态都可以变为外部状态,也就是说,对象状态可以由其使用的上下文来决定。
  3. 细粒度对象

    • 应用程序不依赖于对象身份。由于享元对象可以被共享,对于概念上明显有别的对象,标识测试会返回真。

结构

享元模式包含以下几个核心角色:

享元工厂(Flyweight Factory):

负责创建和管理享元对象,通常包含一个池(缓存)用于存储和复用已经创建的享元对象。

具体享元(Concrete Flyweight):

实现了抽象享元接口,包含了内部状态和外部状态。内部状态是可以被共享的,而外部状态则由客户端传递。

抽象享元(Flyweight):

定义了具体享元和非共享享元的接口,通常包含了设置外部状态的方法。

客户端(Client):

使用享元工厂获取享元对象,并通过设置外部状态来操作享元对象。客户端通常不需要关心享元对象的具体实现。

实现示例(Java)

以下是一个简单的享元模式的实现示例,展示如何利用共享技术来管理字符的实例。

1. 定义享元接口
public interface Flyweight {void operation(String extrinsicState);
}
2. 创建具体享元类
public class ConcreteFlyweight implements Flyweight {private String intrinsicState;public ConcreteFlyweight(String intrinsicState) {this.intrinsicState = intrinsicState;}public void operation(String extrinsicState) {System.out.println("Intrinsic State = " + intrinsicState + ", Extrinsic State = " + extrinsicState);}
}
3. 创建享元工厂类
import java.util.HashMap;
import java.util.Map;public class FlyweightFactory {private Map<String, Flyweight> flyweights = new HashMap<>();public Flyweight getFlyweight(String key) {if (!flyweights.containsKey(key)) {flyweights.put(key, new ConcreteFlyweight(key));}return flyweights.get(key);}
}
4. 客户端代码
public class Client {public static void main(String[] args) {FlyweightFactory factory = new FlyweightFactory();Flyweight flyweightA = factory.getFlyweight("A");Flyweight flyweightB = factory.getFlyweight("B");Flyweight flyweightA2 = factory.getFlyweight("A");flyweightA.operation("First Call");flyweightB.operation("Second Call");flyweightA2.operation("Third Call");}
}

优点

  1. 减少对象的创建

    • 享元模式可以极大地减少系统中对象的数量,降低系统内存的消耗,提高效率。
  2. 外部状态独立

    • 外部状态相对独立,不影响内部状态,使得享元对象可以在不同的环境中被共享。

缺点

  1. 复杂性增加

    • 使系统设计更加复杂,需要将对象的状态外部化,分离内部和外部状态,使得程序的逻辑复杂化。
  2. 线程安全问题

    • 在多线程环境下,共享的享元对象可能会引起线程安全问题,需要进行适当的同步处理。

类图

Client|v
FlyweightFactory ----> Flyweight <---- ConcreteFlyweight

总结

享元模式是一种结构型设计模式,它通过共享技术有效地支持大量细粒度对象的使用,适用于那些需要优化内存使用且对象数量巨大的系统。通过合理的使用享元模式,开发者可以在性能和资源利用之间找到一个良好的平衡点。然而,设计和实现享元模式需要仔细考虑如何分离内部状态和外部状态,确保系统的高效运行同时,也要注意不增加过多的运行时负担。

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 如何成为互联网数据淘金者?爬虫管理平台助您一臂之力
  • 【088】基于SpringBoot+Vue实现高校就业管理系统
  • Linux 忘记root密码,通过单用户模式修改
  • 无人机之电池保养
  • 【数据分享】2021-2100年中国1km分辨率多情景多模式逐月降水量数据集
  • 睿考网:一级建造师考试题型分值介绍
  • 创建React 项目的几种方式
  • Apache防盗链、网页压缩、网页缓存
  • 【区块链 + 智慧政务】都江堰区块链公共服务应用平台 | FISCO BCOS应用案例
  • 数据守卫者:sklearn中的异常点检测技术
  • [XCUITest] 处理iOS权限点击授权 有哪些权限?
  • 【YOLOv5/v7改进系列】改进池化层为SimSPPF
  • 如何部署本地dockers镜像源
  • [RK3308H_Linux] 关于8+2(8路模拟麦克风 + 2路es7243e回采)的调试心得
  • UKP3D的局域网授权程序问题
  • 《Java8实战》-第四章读书笔记(引入流Stream)
  • 【399天】跃迁之路——程序员高效学习方法论探索系列(实验阶段156-2018.03.11)...
  • cookie和session
  • JDK9: 集成 Jshell 和 Maven 项目.
  • LintCode 31. partitionArray 数组划分
  • PHP 使用 Swoole - TaskWorker 实现异步操作 Mysql
  • python 学习笔记 - Queue Pipes,进程间通讯
  • 大整数乘法-表格法
  • 模型微调
  • 通过来模仿稀土掘金个人页面的布局来学习使用CoordinatorLayout
  • 我这样减少了26.5M Java内存!
  • 小而合理的前端理论:rscss和rsjs
  • 验证码识别技术——15分钟带你突破各种复杂不定长验证码
  • ​学习一下,什么是预包装食品?​
  • # 再次尝试 连接失败_无线WiFi无法连接到网络怎么办【解决方法】
  • #07【面试问题整理】嵌入式软件工程师
  • $.ajax中的eval及dataType
  • %@ page import=%的用法
  • (poj1.2.1)1970(筛选法模拟)
  • (八)c52学习之旅-中断实验
  • (二)WCF的Binding模型
  • (二)学习JVM —— 垃圾回收机制
  • (附源码)springboot工单管理系统 毕业设计 964158
  • (黑客游戏)HackTheGame1.21 过关攻略
  • (力扣)1314.矩阵区域和
  • (六)DockerCompose安装与配置
  • (欧拉)openEuler系统添加网卡文件配置流程、(欧拉)openEuler系统手动配置ipv6地址流程、(欧拉)openEuler系统网络管理说明
  • (实战篇)如何缓存数据
  • (原)本想说脏话,奈何已放下
  • (转)Linux整合apache和tomcat构建Web服务器
  • **PHP分步表单提交思路(分页表单提交)
  • .NET Standard 的管理策略
  • .NET/C# 获取一个正在运行的进程的命令行参数
  • .NET/C# 中你可以在代码中写多个 Main 函数,然后按需要随时切换
  • .Net插件开发开源框架
  • .net用HTML开发怎么调试,如何使用ASP.NET MVC在调试中查看控制器生成的html?
  • .php结尾的域名,【php】php正则截取url中域名后的内容
  • @SuppressWarnings注解
  • [ SNOI 2013 ] Quare
  • [3D游戏开发实践] Cocos Cyberpunk 源码解读-高中低端机性能适配策略