设计模式 -第1部分 避免浪费- 第1章 Flyweight 模式 - 共享对象避免浪费

news2025/1/10 1:28:30

第1部分 避免浪费

注:其内容主要来自于【日】-结城浩 著《图解设计模式》20章节 极力推荐大家阅读原著

第1章 Flyweight 模式 - 共享对象避免浪费

image-20230525135640753

1.1 Flyweight 模式

Flyweight 的意思"轻量级",其在英文中的原意指比赛中选手体重最轻等级的一种描述。所以顾名思义,该模式的主要作用就是为了让对象变得更"轻"。

那么这里的"轻"又如何理解呢?

在计算机的应用体系当中,所有的一切应用层的东西都是虚拟的,而这些虚拟的构建都存储在内存当中。所以这里的"轻"代指的就是一个对象所占内存的空间大小。占用空间的比率越大则越"重",反之则"轻"。

举个例子,比如说我们在 Java 当中需要创建一个对象,该对象的本身生成的中间过程比较复杂,也使得该对象比较庞大,内存分配给该对象的占用比也就响应的比距大。当程序在执行过程当中,如果大量的需要使用到该对象,先不谈,该对象每次一的 new 关键字所带来的资源上的负荷,就其该对象如果都使用 new 关键字来进行分配,将会消耗大量的内存空间。

所以关于 Flyweight 模式,其实最终的目的就是为了“尽量的通过共享实例取代 new 实例”。

相当于我们有一个共享池,在共享池中只存在唯一不同实例,公用已经存在的实例。这就是 Flyweight 模式的核心重点。

1.2 实例程序

这里先使用 Flyweight 模式设计一个简单的示例程序。

其具体的程序目的就是将其下 代码清单中 20-1 ~ 20-9 中的许多普通文本组合成一个 “大型字符”的类,而这些普通字符的实例就是重复的实例。

而下面的代码清单中的各个以 bigx.txt 命名的文件,是为了方便进行测试,而通过文本的格式将单个普通字符存储到本地文件当中,在拼接"大型字符"的时候,将其需要的文件内容加载读取到内存当中。

image-20230525140625980

image-20230525140649139

image-20230525140704274

关于类的构建说明如表 20-1 下图所示

这里我用其他字符格式代替需要的可复制或该网站生成 BootSchool

代码清单 1.1 BootSchool banner图

 __      _______    ______    
/  \    / ___   )  / ___  \   
\/) )   \/   )  |  \/   \  \  
  | |       /   )     ___) /  
  | |     _/   /     (___ (   
  | |    /   _/          ) \  
__) (_  (   (__/\  /\___/  /  
\____/  \_______/  \______/    
    ___      _______     ______ 
   /   )    (  ____ \   / ____ \
  / /) |    | (    \/  ( (    \/
 / (_) (_   | (____    | (____  
(____   _)  (_____ \   |  ___ \ 
     ) (          ) )  | (   ) )
     | |    /\____) )  ( (___) )
     (_)    \______/    \_____/ 
 ______      _____      _____
/ ___  \    / ___ \    / ___ \
\/   )  )  ( (___) )  ( (   ) )
    /  /    \     /   ( (___) |
   /  /     / ___ \    \____  |
  /  /     ( (   ) )        ) |
 /  /      ( (___) )  /\____) )
 \_/        \_____/   \______/

image-20230525140739332

BigChar 表示 “大型字符” 的类,该类的主要作用就是通过文件流的形式将其上述代码清单 20-8 中提到的内容读取到内存当中,然后通过 print 方法打印输出大型字符。而这些大型字符,在创建的过程当中会消耗大量的计算机内存资源,因此我们考虑的重点是在于,如何通过共享的形式,将这些唯一的 BigChar 实例作为其共享资源。

BigCharFactory 工厂的作用就是,会更具其具体的需要从而生成指定而 BigChar 实例,但是在其生成之前首先会进行相应的具体判断,如果其发现之前已经生成过该唯一的 BigChar 实例,则直接使用即可,否则生成新的唯一实例。而对于生成的实例,我们将其存储在 java.util.HashMap 类定义的 pool 字段当中,进行维护。

BigString 类的作用就是将其 BgiChar “大型字符” 组合成指定“大型字符串” 。

Main 类用于最终测试程序行为的类。

实例程序 UML 类图

image-20230525144022968

代码清单 1.1 BigChar 类 (BigChar.java)

package com.peggy.flyweight.example01;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;

/**
 * @Projectname: designPatterns
 * @Filename: BigChar
 * @Author: peggy
 * @Data:2023/5/25 11:14
 * @Description: 根据字符生成字符串
 */

public class BigChar {

    //字符名字
    private char charname;

    //大型字符对应的字符串
    private String fontdata;

    //字符串文件路径
    private static String PATH = "E:\\workspaces\\java\\designPatterns\\peggy-flyweight-pattren-01\\src\\main\\resources\\";

    public BigChar(char charname) {
        this.charname = charname;
        try {
            BufferedReader reader = new BufferedReader(
                    new FileReader(PATH + "big" + charname + ".txt"));
            String line;
            StringBuilder buf = new StringBuilder();
            while ((line = reader.readLine()) != null) {
                //写入到内存
                buf.append(line);
                buf.append("\n");
            }
            this.fontdata = buf.toString();

        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    public void print() {
        System.out.println(fontdata);
    }
}

代码清单 1.1 BigCharFactory类 (BigCharFactory.class)

  • !标注[1] 处 BigCharFactory 声明成静态单利模式,是为了保证全局只有一个静态工厂 BigCharFactory 实例。试想如果全局中为私有化其构造方法,就可以创建多个工厂实例,其每个工厂实例都会有一个 pool ,也就失去了 Flyweight 模式存在的意义。
  • !标注[2] 处对于 getBigchar 方法用其 synchronized 关键字进行修饰,其目的也是为了保证 pool 的对象不会重复创建。值得注意的是,虽然无论是否在并发情况下, pool 中的实例受 Map 集合的 Key / Value 键值对的约束,都是有且只有一个唯一的不同实例存在。但是这并不影响在并发情况下出现,BigChar 实例重复创建的可能性存在。所以这里使用 synchronized 关键字修饰是显得尤为重要的。
package com.peggy.flyweight.example01;

import java.util.HashMap;
import java.util.Map;

/**
 * @Projectname: designPatterns
 * @Filename: BigCharFactory
 * @Author: peggy
 * @Data:2023/5/25 14:48
 * @Description: 生成  BigChar 实例的工厂 实现其共享功能
 */

public class BigCharFactory {

    //管理已经生成的 BigChar 实例
    private Map<String, BigChar> pool = new HashMap<>();
    //单利模式,其保证只有一个工厂对象
    /*!标注[1]*/
    private static BigCharFactory singleton = new BigCharFactory();

    private BigCharFactory() {
    }

    public static BigCharFactory getSingleton() {
       return singleton;
    }

    //生成共享 BigChar 唯一对象
    /*!标注[2]*/
    public synchronized  BigChar getBigChar(char charname) {
        BigChar bc = pool.get(String.valueOf(charname));
        if (bc == null) {
            bc = new BigChar(charname);
            pool.put(String.valueOf(charname), bc);
        }
        return bc;
    }
}

代码清单 1.1 BigString类 (BigString.class)

package com.peggy.flyweight.example01;

/**
 * @Projectname: designPatterns
 * @Filename: BigString
 * @Author: peggy
 * @Data:2023/5/25 15:15
 * @Description: 大型字符串创建类
 */

public class BigString {
    //"大型字符" 的数组
    private BigChar[] bigChars;

    //构造函数
    public BigString(String string) {
        bigChars = new BigChar[string.length()];
        BigCharFactory factory = BigCharFactory.getSingleton();
        for (int i = 0; i < bigChars.length; i++) {
            bigChars[i] = factory.getBigChar(string.charAt(i));
        }
    }

    //打印显示
    public void print() {
        for (int i = 0; i < bigChars.length; i++) {
            bigChars[i].print();
        }
    }
}

image-20230525152457323

Main 类

package com.peggy.flyweight.example01;

/**
 * @Projectname: designPatterns
 * @Filename: Main
 * @Author: peggy
 * @Data:2023/5/25 15:25
 * @Description: 案例测试类
 */

public class Main {
    public static void main(String[] args) {
        BigString bs = new BigString("15569732xxx");
        bs.print();
    }
}
image-20230525154918578

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

迪赛智慧数——饼图柱状图(基本饼图和基本柱状图):“怒路症”数据解读

效果图 35%的司机承认自己属于“路怒族”&#xff0c;还有65%的人表示自己不是“路怒族”。 近日&#xff0c;上海两车高架上斗气碰撞差点掉落高架&#xff0c;上海高架出现“史诗级”斗气车。小编在此呼吁大家&#xff0c;开车路上减压&#xff0c;避免坏情绪伴随&#xff0c…

DDoS攻击与防御(一)

前言 这章主要讲述DDoS攻击与防御方式 理论知识来源于 https://www.microsoft.com/zh-cn/security/business/security-101/what-is-a-ddos-attack 1&#xff1a;攻击 一般来说&#xff0c;DDoS 攻击分为三大类&#xff1a;容量耗尽攻击、协议攻击和资源层攻击。 1>容量耗尽…

shiro基于redis实现分布式权限管理,在加入shiro的缓存管理后,项目报错

shiro基于redis实现分布式权限管理&#xff0c;在加入shiro的缓存管理后&#xff0c;项目报错 报错信息概括解决其他详细报错信息 报错信息概括 2023-05-24 16:27:56.374 ERROR 28740 --- [nio-8092-exec-6] o.a.s.web.servlet.AbstractShiroFilter : session.touch() method …

水处理计算常用表格大全

第二章 设计方案城市污水处理厂的设计规模与进入处理厂的污水水质和水量有关&#xff0c;污水的水质和水量可以通过设计任务书的原始资料计算。2.1 厂址选择在污水处理厂设计中&#xff0c;选定厂址是一个重要的环节&#xff0c;处理广的位置对周围环境卫生、基建投资及运行管理…

加强密码安全,保护您的账户——ADSelfService Plus

在当今数字化时代&#xff0c;密码安全成为了每个人都需要关注的重要问题。随着越来越多的个人和组织依赖于互联网和电子系统进行业务和通信&#xff0c;确保账户的安全性变得尤为关键。在这方面&#xff0c;ADSelfService Plus是一个功能强大的解决方案&#xff0c;为用户提供…

版图设计工具解析-virtuoso的display.drf文件解析

1. display.drf文件解析 virtuoso的版图颜色定义分析 下图为virtuoso的版图颜色&#xff0c;包括填充&#xff0c;轮廓&#xff0c;彩点&#xff0c;线形 本文以smic18mmrf的display.drf文件进行解析 smic18的PDK包下存在display.drf文件 打开文件display.drf文件后看到如下…

ApiKit 简介安装以及如何使用

一、介绍 ApiKit 是接口管理、开发、测试全流程集成工具&#xff0c;定位 API 管理 Mock 自动化测试 异常监控 团队协作。 1、开发测试过程中的现状 yapi -- 管理接口文档 rap -- 前端开发mock数据 postman -- 开发调试接口、测试调用接口 jmeter -- 基本的压力测试 2…

1个普通Java程序员需要具备什么样的素质和能力才可以称得上高级工程师?

1个Java程序员具备什么样的素质和能力才可以称得上高级工程师&#xff1f; 这个问题也引发了我的一些思考&#xff0c;可能很多人会说&#xff0c;“作为高级工程师&#xff0c;基础得过硬、得熟练掌握一门编程语言、至少看过一个优秀开源项目的源代码、有过高并发/性能优化的…

【RocketMQ】RocketMQ入门

【RocketMQ】RocketMQ入门 文章目录 【RocketMQ】RocketMQ入门1. 消费模式2. 发送/消费 消息2.1 同步消息2.2 异步消息2.3 单向消息2.4 延迟消息2.5 批量消息2.6 顺序消息 1. 消费模式 MQ的消费模式大致分为两种&#xff0c;一种是推Push&#xff0c;一种是拉pull。 Push模式…

在变压器厂中使用 ISA-95 应用程序进行调度集成

介绍 在工业批量和连续生产/运营环境中&#xff0c;调度涉及将诸如罐、反应器和其他加工设备之类的资源分配给生产/运营任务。第 4 层生产/运营计划确定要制造什么产品、要制造多少产品以及何时制造。根据设备、物料、人员和班次的可用性&#xff0c;随着时间的推移分配资源。…

CSDN中如何获得铁粉(用心篇)

✅作者简介&#xff1a;2022年博客新星 第八。热爱国学的Java后端开发者&#xff0c;修心和技术同步精进。 &#x1f34e;个人主页&#xff1a;Java Fans的博客 &#x1f34a;个人信条&#xff1a;不迁怒&#xff0c;不贰过。小知识&#xff0c;大智慧。 &#x1f49e;当前专栏…

快速实现pytest自定义配置项,让Web自动化测试更便捷!

目录 前言&#xff1a; 一、什么是pytest.ini 二、在pytest.ini中添加自定义配置项 三、使用自定义配置项 四、结论 前言&#xff1a; WEB自动化测试是一个重要的环节&#xff0c;需要结合框架和工具进行开发。在WEB自动化测试中&#xff0c;常用的是pytest框架&#xff…

go sync包

官方文档&#xff1a;https://pkg.go.dev/sync 临界区 临界区(critical section)是指包含有共享数据的一段代码&#xff0c;这些代码可能被多个线程访问 或修改。临界区的存在就是为了保证当有一个线程在临界区内执行的时候&#xff0c;不能有其他任何线程被允许在临界区执行…

workquue

参考 讲解Linux内核工作队列workqueue源码分析 - 知乎 浅谈Linux内核中断下半部——工作队列&#xff08;work queue&#xff09; - 知乎 kernel/workqueue.c 初始化 /** 6004 * workqueue_init_early - early init for workqueue subsystem 6005 * 6006 * This is th…

字节测开5年经验之谈,1分钟了解自动化测试..

引子 写在最前面&#xff1a;目前自动化测试并不属于新鲜的事物&#xff0c;或者说自动化测试的各种方法论已经层出不穷&#xff0c;但是&#xff0c;能够明白自动化测试并很好落地实施的团队还不是非常多&#xff0c;我们接来下用通俗的方式来介绍自动化测试…… 本文共有2410…

WebSocket全双工通信SpringBoot实现

【IT老齐238】十分钟上手WebSocket全双工通信协议_哔哩哔哩_bilibili【IT老齐238】十分钟上手WebSocket全双工通信协议, 视频播放量 8348、弹幕量 23、点赞数 318、投硬币枚数 157、收藏人数 257、转发人数 30, 视频作者 IT老齐, 作者简介 老齐的个人V: itlaoqi001 ~~欢迎前来交…

kubernetes01

kubernetes基础 kubernetes介绍 Kubernetes是Google在2014年开源的一款容器集群系统&#xff0c;简称k8s Kubernetes用于容器化应用程序部署、扩展和管理&#xff0c;目标是让容器化应用简单高效 官方网站&#xff1a;https://kubernetes.io/ 官方文档&#xff1a;https://ku…

PFC(Priority Flow Control)及PFC Storm介绍

文章目录 PFCPFC Storm PFC PFC是一种流量控制机制&#xff0c;用于保证网络中的无损传输&#xff0c;常用于RDMA网络中&#xff0c;以下具体介绍其机制。 如图所示&#xff0c;发送方的出端口发送数据包给接收方的入端口。在发送方的出端口&#xff0c;数据包在至多八个队列中…

AI智能照片编辑:AI Photo for Mac

AI Photo是一款Mac平台上的智能照片编辑软件&#xff0c;它基于人工智能技术&#xff0c;可以帮助用户快速、轻松地对照片进行编辑和美化。AI Photo提供了多种智能修复和美化功能&#xff0c;包括自动调整色彩、对比度、亮度、清晰度等&#xff0c;使得照片的质量得到有效提升。…

二叉树:填充每个节点的下一个右侧节点指针(java)

leetcode116:填充每个节点的下一个右侧节点指针 leetcode原题链接&#xff1a;题目描述递归解法一递归方法二&#xff08;效率更高&#xff09;二叉树专题 leetcode原题链接&#xff1a; 116题&#xff1a;填充每个节点的下一个右侧节点指针 题目描述 给定一个 完美二叉树 &a…