Author:Gorit
Date:2021年11月26日
Refer:《图解设计模式》

20.1 Flyweight 模式

“Flyweight” 是“轻量级”的意思,指的是拳击比赛中选手体重最轻等级。所以,该设计模式的作用是为了让对象变“轻”。

在计算机中,“对象”是抽象的东西,它所用的“重量”是指在计算机中的所使用的内存大小。

Java 中,我们通过 new 关键字来生成对象,但是如果一次性生成太多对象,计算机可能就会内存不足,而负担不起。

关于 Flyweight 模式,就是“通过尽量共享实例来避免 new 实例”

因此,尽可能使用已存在的内存实例

20.2 示例程序

模拟数据:(太长就懒得手敲了)
技术专题 2021-11-26 23.24_1.jpg技术专题 2021-11-26 23.24_2.jpg
我们会写程序,来读取这些文件

类名 说明
BigChar 表示“大型字符”的类
BigCharFactory 表示生成和共用 BigChar 类的实例的类
BigString 表示多个 BigChar 组成大型“字符”的类
Main 测试程序行为

BigChar

  1. package Flyweight;
  2. import java.io.BufferedReader;
  3. import java.io.FileNotFoundException;
  4. import java.io.FileReader;
  5. import java.io.IOException;
  6. /**
  7. * @Author Gorit
  8. * @Date 2021/11/26
  9. **/
  10. public class BigChar {
  11. // 字符名字
  12. private char charname;
  13. // 大型字符串对应字符串(由 # . \n)组成
  14. private String fontData;
  15. public BigChar(char charname) {
  16. this.charname = charname;
  17. try {
  18. BufferedReader reader = new BufferedReader(
  19. new FileReader("big" + charname + ".txt")
  20. );
  21. String line;
  22. StringBuffer buf = new StringBuffer();
  23. while ((line = reader.readLine()) != null) {
  24. buf.append(line);
  25. buf.append("\n");
  26. }
  27. reader.close();
  28. this.fontData = buf.toString();
  29. } catch (IOException e) {
  30. e.printStackTrace();
  31. }
  32. }
  33. // 显示大型字符
  34. public void print () {
  35. System.out.println(fontData);
  36. }
  37. }

BigCharFactory

  1. package Flyweight;
  2. import java.util.HashMap;
  3. /**
  4. * @Author Gorit
  5. * @Date 2021/11/26
  6. **/
  7. public class BigCharFactory {
  8. // 管理已经生成的 BigChar 实例
  9. private HashMap pool = new HashMap(16);
  10. // Singleton 模式
  11. private static BigCharFactory singleton = new BigCharFactory();
  12. public BigCharFactory() {
  13. }
  14. // 获取唯一实例
  15. public static BigCharFactory getInstance() {
  16. return singleton;
  17. }
  18. // 生成(共享)BigChar 实例 (使用 synchronized 保证在多线程中原子性)
  19. public synchronized BigChar getBigChar(char charname) {
  20. BigChar br = (BigChar) pool.get("" + charname);
  21. if (br == null) {
  22. br = new BigChar(charname); // 生成 BigChar 实例
  23. pool.put("" + charname, br);
  24. }
  25. return br;
  26. }
  27. }

BigString

  1. package Flyweight;
  2. import java.util.HashMap;
  3. /**
  4. * @Author Gorit
  5. * @Date 2021/11/26
  6. **/
  7. public class BigCharFactory {
  8. // 管理已经生成的 BigChar 实例
  9. private HashMap pool = new HashMap(16);
  10. // Singleton 模式
  11. private static BigCharFactory singleton = new BigCharFactory();
  12. public BigCharFactory() {
  13. }
  14. // 获取唯一实例
  15. public static BigCharFactory getInstance() {
  16. return singleton;
  17. }
  18. // 生成(共享)BigChar 实例 (使用 synchronized 保证在多线程中原子性)
  19. public synchronized BigChar getBigChar(char charname) {
  20. BigChar br = (BigChar) pool.get("" + charname);
  21. if (br == null) {
  22. br = new BigChar(charname); // 生成 BigChar 实例
  23. pool.put("" + charname, br);
  24. }
  25. return br;
  26. }
  27. }

Main

  1. package Flyweight;
  2. import java.util.Scanner;
  3. /**
  4. * @Author Gorit
  5. * @Date 2021/11/27
  6. **/
  7. public class Main {
  8. public static void main(String[] args) {
  9. // if (args.length == 0) {
  10. // System.out.println("Usage: java Main digits");
  11. // System.out.println("Example: java Main 123123");
  12. // System.exit(0);
  13. // }
  14. Scanner sc = new Scanner(System.in);
  15. System.out.println("请输入你要打印的字符数字:(比如 123131)");
  16. String nums = sc.next();
  17. BigString bs = new BigString(nums);
  18. bs.print();
  19. }
  20. }

怎么实现共享呢?

比如我们输入 123123,打印过一次 1 之后,1 就会被存进 HashMap,当再次需要时,如果存在,就直接使用,因此就不会创建实例了

20.3 Flyweight 中登场的角色

一、Flyweight(轻量级)

减少类的代码数量,Flyweight 表示的就是实例会被共享的类

二、FlyweightFactory(轻量级工厂)

前面学过 Factory 模式,FlyweightFactory 就是生产 Flyweight 实例的工厂,同时实现共享实例

四、Client(请求者)

Client 角色 使用 FlyweightFactory 生成的 Flyweight 实例,由 BigString 扮演此角色

20.4 相关设计模式

一、Proxy 模式

如果生成实例处理的时间比较长,那么使用 Flyweight 模式可以提高程序处理的速度

而 Proxy 模式则是通过设置代理提高程序的处理速度

二、Composite 模式

有时可以使用 Flyweight 模式共享 Composite 模式中的 Leaf 角色

三、Singleton 模式

FlyweightFactory 角色有时会使用 Singleton 模式