23种设计模式之享元模式

享元模式

1、定义

享元模式:运用共享技术有效的支持大量细粒度对象的复用

2、享元模式结构

  • Flyweight(抽象享元类):通常是一个接口或抽象类,在抽象享元类中声明了具体享元类公共的方法,这些方法可以向外界提供享元对象的内部数据(状态),同时也可以通过这些方法来设置外部数据(状态)
  • ConcreteFlyweight(具体享元类):实现抽象享元类,其实例称为享元对象,在具体享元类中为内部状态提供了存储空间。通常可以结合单例模式来设计具体享元类,为每一个具体享元类提供唯一的享元对象
  • UnsharedConcreteFlyweight(非共享具体享元类):并不是所有的抽象享元类的子类都需要被共享,不能被共享的子类可设计为非共享具体享元类。可直接通过实例化创建
  • FlyweightFactory(享元工厂类):用于创建并管理享元对象

享元模式结构图

3、示例

开发一个围棋软件,会发现棋子的形状大小完全相同,只是颜色和位置不同。如果每个棋子都作为一个独立的对象存储在内存中,会导致需要大量的内存空间,为了解决这个问题,可以用到享元模式

围棋棋子类

public abstract class IgoChessman {
    public abstract String getColor();

    public void display() {
        System.out.println("棋子颜色:" + this.getColor());
    }
}

黑子、白子具体实现类

public class BlackIgoChessman extends IgoChessman{
    @Override
    public String getColor() {
        return "黑色";
    }
}
public class WhiteIgoChessman extends IgoChessman {
    @Override
    public String getColor() {
        return "白色";
    }
}

棋子工厂类 使用了单例模式对其进行设计

public class IgoChessmanFactory {

    private static IgoChessmanFactory instance = new IgoChessmanFactory();
    private static Hashtable hashtable;

    private IgoChessmanFactory() {
        hashtable = new Hashtable();
        IgoChessman black,white;
        black = new BlackIgoChessman();
        hashtable.put("black", black);
        white = new WhiteIgoChessman();
        hashtable.put("white", white);
    }

    public static IgoChessmanFactory getInstance() {
        return instance;
    }

    public IgoChessman getIgoChessman(String color) {
        return (IgoChessman) hashtable.get(color);
    }
}

Client

public class Client {

    public static void main(String[] args) {
        IgoChessman black1, black2, white1, white2;
        IgoChessmanFactory factory;

        factory = IgoChessmanFactory.getInstance();

        black1 = factory.getIgoChessman("black");
        black2 = factory.getIgoChessman("black");
        System.out.println("判断两颗黑子是否相同:" + (black1 == black2));

        white1 = factory.getIgoChessman("white");
        white2 = factory.getIgoChessman("white");
        System.out.println("判断两颗白子是否相同:" + (white1 == white2));

        black1.display();
        white1.display();
    }
}

输出结果

判断两颗黑子是否相同:true
判断两颗白子是否相同:true
棋子颜色:黑色
棋子颜色:白色

4、享元模式优缺点

4.1优点
  • 可以减少内存中对象的数量,节约系统资源,提高系统性能(String类
  • 享元模式的外部状态相对独立,不会影响其内部状态,从而使享元对象可以再不同环境中被使用
4.2缺点
  • 使系统变得复杂,需要分离出内部状态和外部状态
  • 为了使对象可以共享,需要将享元对象的部分状态外部化,读取外部状态将使运行时间变长

5、享元模式适用环境

当都具备下列情况时,使用Flyweight模式:

1.一个应用程序使用了大量的对象。

2.完全由于使用大量的对象,造成很大的存储开销。

3.对象的大多数状态都可变为外部状态。

4.如果删除对象的外部状态,那么可以用相对较少的共享对象取代很多组对象。

5.应用程序不依赖于对象标识。Flyweight对象可以被共享。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

从多线程设计模式到对 CompletableFuture 的应用

大家好,我是 方圆。最近在开发 延保服务 频道页时,为了提高查询效率,使用到了多线程技术。为了对多线程方案设计有更加充分的了解,在业余时间读完了《图解 Java 多线程设计模式》这本书,觉得收获良多。本篇文章将介绍其…

几种经典查找算法

几种经典查找算法 顺序查找法二分查找法判定树 二叉查找树(BST)索引查找B-树B树散列表(hash)查找 顺序查找法 顺序查找的平均查找长度为: 时间复杂度为0(n); 二分查找法 int bin…

CNN学习(7):用C++实现简单不同参数的卷积模型

目录 一、参数说明和计算公式 1、符号约定 2、输出大小计算公式 二、不同类型的卷积 1、输入3*3*1,卷积核3*3*1,输出1*1*1 (1)实现代码 (2)代码说明 2、输入4*4*1,卷积核3*3*1&#xff…

环保评A的意义与价值

环保评A,这个看似简单的称谓,背后却蕴藏着深厚的环保理念和实践标准。在当今社会,环保已经成为一项全球性的议题,各国都在努力推动绿色发展,实现可持续发展目标。那么,环保评A究竟是全国性的认证还是地方性…

Java SSTI服务端模版注入漏洞原理与利用

文章目录 前言Velocity基础语法基础示例命令执行 靶场实践漏洞代码漏洞验证检测工具 FreeMarker基础示例漏洞示例CMS案例 Thymeleaf基础示例漏洞示例安全方案 总结 前言 SSTI(Server Side Template Injection)全称服务端模板注入漏洞,在 Jav…

开放式耳机值得入手买吗?可以对比这几款开放式耳机看看

居家办公时,选择一款合适的耳机能够有效地提高工作效率。入耳式耳机虽然能够有效地隔绝外界噪音,但长时间佩戴会对耳朵造成负担,甚至引发耳道感染。而头戴式耳机虽然能够提供更好的音质,但体积较大,佩戴起来不够灵活。…

PyTorch -- Batch Normalization(BN) 快速实践

Batch Normalization 可以 改善梯度消失/爆炸问题:前面层的梯度经过多次传递后会变得非常小(大),从而导致网络收敛速度慢(不收敛),应用 BN 可缓解加速网络收敛:BN 使得每个神经元的输入分布更加稳定减少过拟合:BN 可减…

求导,积分

求导公式: 复合函数求导法则:两个函数导函数的乘积. 例如:f(x)2x1,f(x)2,g(x)x^24x4,g(x)2x4 那么复合函数: g(f(x))(2x1)^24(2x1)4 把(2x1)看做整体,则g2(2x1)4 然后再求(2x1)的导函…

LeetCode | 2879.显示前三行

在 pandas 中,可以使用 head() 方法来读取 DataFrame 的前几行数据。如果想读取指定数量的行,可以在 head() 方法中传入一个参数 n,读取前 n 行 import pandas as pddef selectFirstRows(employees: pd.DataFrame) -> pd.DataFrame:retur…

Dictionary 字典

文章目录 一、什么是字典1.1 字典的创建方式 一、什么是字典 字典: 用来存储数据,与列表和元组不一样的是,字典以键值对的形式对数据进行存储,也就是 key 和 value。相当于 Java 中的 Map。 注意: 1、 key 的值不可重…

C++进阶(一)

个人主页:PingdiGuo_guo 收录专栏:C干货专栏 前言 本篇博客是讲解函数的重载以及引用的知识点的。 文章目录 前言 1.函数重载 1.1何为函数重载 1.2函数重载的作用 1.3函数重载的实现 2.引用 2.1何为引用 2.2定义引用 2.3引用特性 2.4常引用 2…

认识一些分布函数-Frechet分布及其应用

1. 何为Frechet分布 Frechet分布也称为极值分布(EVD)类型II,用于对数据集中的最大值进行建模。它是四种常用极值分布之一。另外三种是古贝尔分布、威布尔分布和广义极值分布(Gumbel Distribution, the Weibull Distribution and the Generalized Extreme Value Distributi…

34 Debian如何配置ELK群集

作者:网络傅老师 特别提示:未经作者允许,不得转载任何内容。违者必究! Debian如何配置ELK群集 《傅老师Debian知识库系列之34》——原创 ==前言== 傅老师Debian知识库特点: 1、拆解Debian实用技能; 2、所有操作在VMware虚拟机实测完成; 3、致力于最终形成Debian知识手…

LVS-DR模式详解:提升网站性能的最佳解决方案

LVS-DR模式原理 用户请求到达Director Server: 用户请求到达Director Server(负载均衡服务器),数据包首先到达内核空间的PREROUTING链。数据包源IP:CIP,目标IP:VIP,源MAC&#xff1a…

【内存管理之C语言数组】

1.栈空间上的C数组 糟糕的可用性,但是你将在遗留代码中见到它们 相同类型的对象的内存块 大小必须是常量表达式 第一个元素索引为0 2.指针和C数组 更奇怪的是:数组标识符退化为指向第一个元素的指针 3.访问数组 4.堆空间上的C数组 相同类型的对象的内…

数据库开发——并发控制(第十一章)

文章目录 前言并发执行例题一、封锁二、封锁协议三、可串行调度四、总结 学习目标:重点为并发控制的基本概念及几个基本协议 前言 数据库管理系统必须提供并发控制机制,保证事务的隔离性和一致性 并发执行例题 一、封锁 排他锁称为写锁,共…

智能化状态管理:自动状态流转处理模块

目录 基本背景介绍 具体实现 基本数据准备 基本数据表 状态转换常量 状态转换注解 任务处理模版 各任务实现逻辑 开启比对任务进行处理 降噪字段处理任务处理 开启业务数据比对处理 业务数据比对处理 开始核对数据生成最终报告处理 核对数据生成最终报告处理 状…

小红书教程简化版,从0开始走向专业,小红书-主理人培养计划 (13节)

课程目录 1-小红书分析与拆解.mp4 2-小红书电商玩法.mp4 3-小红书基础信息设置10_1.mp4 4-小红书如何开店?.mp4 5-小红书店铺设置(1).mp4 5-小红书店铺设置.mp4 6-小红书笔记制作与产品发布.mp4 7-小红书运营的文案与标题.mp4 8-小红…

Spring Boot 自定义Starter

自定义starter 创建pom项目 <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0"xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation"http://maven.ap…

MySQL的三种重要的日志

日志 Mysql有三大日志系统 Undo Log&#xff08;回滚日志&#xff09;&#xff1a;记录修改前的数据&#xff0c;用于事务回滚和 MVCC&#xff08;多版本并发控制&#xff09;。 Redo Log&#xff08;重做日志&#xff09;&#xff1a;记录数据变更&#xff0c;用于崩溃恢复&…