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

第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

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

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

相关文章

【C语言】实现猜数字游戏——随机数

&#x1f6a9;纸上得来终觉浅&#xff0c; 绝知此事要躬行。 &#x1f31f;主页&#xff1a;June-Frost &#x1f680;专栏&#xff1a;C语言 该篇将对 选择与循环语句 进行运用&#xff0c;实现猜数字游戏。 需求&#xff1a;游戏后可以选择再次进行游戏&#xff0c;也可以选择…

「实在RPA·烟草数字员工」助力烟草行业数字化转型加速度

烟草行业作为烟草产业链上重要一环&#xff0c;外部连接烟草工业企业、零售客户、消费者&#xff0c;内部包含营销、专卖、烟叶、物流等诸多业务&#xff0c;信息系统众多&#xff0c;企业数据量庞大。因此&#xff0c;清楚地了解自身存在的痛点&#xff0c;找到适合自身业务需…

如何在华为OD机试中获得满分?Java实现【寻找峰值】一文详解!

✅创作者&#xff1a;陈书予 &#x1f389;个人主页&#xff1a;陈书予的个人主页 &#x1f341;陈书予的个人社区&#xff0c;欢迎你的加入: 陈书予的社区 &#x1f31f;专栏地址: Java华为OD机试真题&#xff08;2022&2023) 文章目录 1. 题目描述2. 输入描述3. 输出描述…

gitbook在centos上安装

1&#xff09;官网下载Node.js的Linux64位的二进制包:Download | Node.js 或者在线下载&#xff1a; wget https://nodejs.org/dist/v12.16.1/node-v12.16.1-linux-x64.tar.xz ​​2)到指定目录​解压 cd /opt/gitbook tar -xJf node-v12.16.1-linux-x64.tar.xz mv node-…

STM32采集传感器数据通过排序取稳定值

一、前言 在物联网、单片机开发中,经常需要采集各种传感器的数据。比如:温度、湿度、MQ2、MQ3、MQ4等等传感器数据。这些数据采集过程中可能有波动,偶尔不稳定,为了得到稳定的值,我们可以对数据多次采集,进行排序,去掉最大和最小的值,然后取平均值返回。 二、排序算法…

运维工程师面试总结(含答案)

运维工程师面试总结 原文链接&#xff1a;https://www.cuiliangblog.cn/detail/article/2 一、linux 1. linux系统启动流程 第一步&#xff1a;开机自检&#xff0c;加载BIOS第二步&#xff1a;读取&#xff2d;&#xff22;&#xff32;第三步&#xff1a;Boot Loader grub…

华为OD机试之真正的密码(Java源码)

真正的密码 题目描述 一行中输入一个字符串数组&#xff0c;如果其中一个字符串的所有以索引0开头的子串在数组中都有&#xff0c;那么这个字符串就是潜在密码在所有潜在密码中最长的是真正的密码&#xff0c;如果有多个长度相同的真正的密码&#xff0c;那么取字典序最大的为…

【ClickHouse】

文章目录 一、表引擎1、表引擎的作用2、TinyLog3、Memory4、MergeTree二、数据库引擎1、作用--跨种类交换数据2、示例 三、MergeTree引擎1、简单使用2、分区partition by3、主键primary key4、order by&#xff08;必填&#xff09; 一、表引擎 1、表引擎的作用 CK表引擎决定…

智能运维应用之道,告别企业数字化转型危机

面临的问题及挑战 数据中心发展历程 2000 年中国数据中心始建&#xff0c;至今已经历以下 3 大阶段。早期&#xff1a;离散型数据中心 IT 因以项目建设为导向&#xff0c;故缺乏规划且无专门运维管理体系&#xff0c;此外&#xff0c;开发建设完的项目均是独立运维维护&#…

【喜闻乐见,包教包会】二分图最大匹配:匈牙利算法(洛谷P3386)

&#x1f3ad;不要管上面那玩意。。。 引入 现在&#xff0c;你&#xff0c;是一位酒店的经理。 西装笔挺&#xff0c;清瘦智慧。 金丝眼镜&#xff0c;黑色钢笔。 大理石的地板&#xff0c;黑晶石的办公桌&#xff0c;晶莹的落地玻璃。 而现在&#xff0c;有几个雍容华贵的…

智慧城市同城V4小程序V2.24独立开源版 + 全插件+VUE小程序开源前端+最新用户授权接口

智慧城市同城V4小程序V2.22开源独立版本月最新版&#xff0c;与上一版相比修复了一些小细节&#xff0c;功能本身并无大的变化。新版系统包含全插件、包括很多稀缺收费的插件都在里面如括招聘、 家政等&#xff0c;外加小程序的VUE开源前端&#xff0c;整个系统全开源&#xff…

机器学习 | 降维:PCA主成分分析

本文整理自 长路漫漫2021的原创博客&#xff1a;sklearn基础篇&#xff08;九&#xff09;-- 主成分分析&#xff08;PCA&#xff09;李春春_的原创博客&#xff1a;主成分分析&#xff08;PCA&#xff09;原理详解bilibili视频&#xff1a;用最直观的方式告诉你&#xff1a;什…

Python中模块的使用方法4

1 模块、包和库的区别 Python中&#xff0c;模块的英文是“module”&#xff0c;是一个以py为后缀名的文件&#xff1b;包的英文是“package”&#xff0c;是一个包含了多个模块的目录&#xff1b;库的英文是“library”&#xff0c;包含了具有相关功能的包和模块。 2 模块的…

web练习第二周

前言&#xff1a;&#xff08;博主个人学习笔记&#xff0c;不用看&#xff09;web练习第二周&#xff0c;仅做出前3题。相比于第一周&#xff0c;难度大幅增加&#xff0c;写题时就算看了wp还是像个无头苍蝇一样到处乱创&#xff0c;大多都是陌生知识点&#xff0c;工具的使用…

LeetCode刷题(ACM模式)-02链表

参考引用&#xff1a;代码随想录 注&#xff1a;每道 LeetCode 题目都使用 ACM 代码模式&#xff0c;可直接在本地运行&#xff0c;蓝色字体为题目超链接 0. 链表理论基础 0.1 链表定义 链表是一种通过指针串联在一起的线性结构&#xff0c;每一个节点由两部分组成&#xff1a…

矿井水除总氮工艺详解

一、项目概述 项目背景: 1、水资源浪费长期以来&#xff0c;采煤对地下水造成了严重破坏。绝大部分矿井水&#xff0c;被以直排方式&#xff0c;流入河道、田野&#xff0c;这不仅造成水资源的白白浪费&#xff0c;也污染了环境。社会对此反响强烈的同时&#xff0c;煤矿企业也…

Live800:客服系统知识库建设中需要注意的三个要点

互联网的快速发展&#xff0c;让客服行业也随之发生着巨大的变化。传统的客服方式越来越难以满足人们的需求&#xff0c;客户对客服的要求也变得越来越高。在这种情况下&#xff0c;客服系统成为了一种必不可少的工具。 客服系统作为企业与客户沟通的重要渠道&#xff0c;其之所…

电脑msvcp120.dll缺失怎么办?由于找不到msvcp120.dll的解决方案

MSVCP120.dll文件是Windows操作系统中的一种动态链接库文件。它是由Microsoft C软件包提供的重要组件。当系统提示“MSVCP120.dll文件缺失”时&#xff0c;可能会导致某些应用程序无法正常运行。 以下是修复MSVCP120.dll缺失问题的几种方法&#xff1a; 方法一&#xff1a;修复…

ChatGPT发展报告:原理、技术架构详解和产业未来(附下载)

今年12月1日&#xff0c;OpenAI推出人工智能聊天原型ChatGPT&#xff0c;再次赚足眼球&#xff0c;为AI界引发了类似AIGC让艺术家失业的大讨论。 据报道&#xff0c;ChatGPT在开放试用的短短几天&#xff0c;就吸引了超过 100 万互联网注册用户。并且社交网络流传出各种询问或…

机试打卡 -12 滑动窗口最大值(优先队列堆)

我的思路1&#xff1a;队列&#xff0c;每次 出队入队&#xff0c;记录1个队列中的最大值索引&#xff0c;超时。。。 class Solution:def maxSlidingWindow(self, nums: List[int], k: int) -> List[int]:nums_lenlen(nums)ans_list[]# 队列长度为kqueuenums[:k]# 队列最大…