笔头云 笔头云
首页
设计模式
SQL教程
Redis
归档
关于
友链

笔头云

非淡泊无以明志,非宁静无以致远。
首页
设计模式
SQL教程
Redis
归档
关于
友链
  • 设计原则
  • 设计模式
  • 单例模式
  • 工厂模式
  • 建造者模式
  • 原型模式
  • 适配器模式
  • 代理模式
  • 装饰器模式
  • 门面模式
  • 桥接模式
  • 享元模式
    • 定义
    • 结构
    • 优点
    • 缺点
    • 应用场景
    • 示例代码1
    • 示例代码2
  • 组合模式
  • 策略模式
  • 模板方法模式
  • 观察者模式
  • 责任链模式
  • 状态模式
  • 迭代器模式
  • 访问者模式
  • 中介模式
  • 命令模式
  • 解释器模式
  • 备忘录模式
  • 设计模式
笔头云
2023-11-08
目录

享元模式

# 享元模式

享元模式是为了对象复用,节省内存,防止对象的频繁创建和销毁。

# 定义

享元模式(Flyweight Pattern)是一种结构设计模式,旨在通过共享对象来减少内存使用和提高性能。它适用于大量细粒度的对象,其中许多对象具有相似的属性和行为。

# 结构

抽象享元(Flyweight):定义享元对象的接口,包含享元对象的公共方法。这个接口可以描述内部状态和外部状态的操作。
具体享元(ConcreteFlyweight):实现抽象享元接口,并存储内部状态。具体享元对象需要注意内部状态的共享和复用,确保可以被多个客户端共享。
享元工厂(Flyweight Factory):负责创建和管理享元对象。它维护一个享元池(或缓存),用于存储已创建的享元对象。当客户端请求获取享元对象时,享元工厂首先检查享元池中是否存在符合要求的对象,如果存在则返回已有的对象,否则创建一个新的对象并将其放入享元池中。
客户端(Client):使用享元对象的客户端。客户端通常会维护一个对享元工厂的引用,并通过享元工厂获取享元对象。客户端需要将外部状态传递给享元对象,以完成具体的操作。

享元模式

- img: https://bitouyun.com/images/design-pattern/flyweight.png
  link: https://bitouyun.com/images/design-pattern/flyweight.png
  name: 享元模式
1
2
3

# 优点

享元模式通过共享内部状态,可以减少系统中对象的数量,节省内存空间。相同或相似的对象可以共享一份内部状态,从而减少了对象的创建和销毁的开销,提升系统的响应速度。

# 缺点

增加了系统复杂性:要分离出外部状态和内部状态,引入享元工厂来管理享元对象,这增加了系统的复杂性。

# 应用场景

享元模式适用于需要创建大量相似对象、希望减少对象数量、节省内存空间并提高系统性能的场景。它可以在对象的内部状态和外部状态之间进行分离,并通过共享内部状态来实现对象的复用。如文字、图像处理、商品、缓存、池管理等。

# 示例代码1

场景1

黑白棋游戏使用享元模式,减少对象的创建,

    /**
     * 棋子
     * 抽象享元接口
     */
    public interface Piece {
      // 设置坐标位置
      void put(int x, int y);
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    /**
     * 黑棋
     * 具体享元类
     */
    @Slf4j
    public class BlackPiece implements Piece {
      @Override
      public void put(int x, int y) {
        log.info("在坐标(x:{},y:{})放置了一个黑棋子", x, y);
      }
    }
    
    /**
     * 白棋
     * 具体享元类
     */
    @Slf4j
    public class WhitePiece implements Piece {
      @Override
      public void put(int x, int y) {
        log.info("在坐标(x:{},y:{})放置了一个白棋子", x, y);
      }
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    /**
     * 棋子工厂类
     * 享元工厂
     */
    @Slf4j
    public class PieceFactory {
      // 棋子map
      private final Map<String, Piece> pieceMap = new HashMap<>();
      // 饿汉式单例
      private static PieceFactory instance = new PieceFactory();
    
      // 私有构造方法
      private PieceFactory() {
      }
    
      // 获取实例
      public static PieceFactory getInstance() {
        return instance;
      }
    
      // 获取棋子对象
      public Piece getPiece(String color) {
        Piece piece = pieceMap.get(color);
        if (piece == null) {
          switch (color) {
            case "black":
              piece = new BlackPiece();
              log.info("创建黑棋");
              break;
            case "white":
              piece = new WhitePiece();
              log.info("创建白棋");
              break;
            default:
              throw new IllegalArgumentException("不支持的颜色:" + color);
          }
          pieceMap.put(color, piece);
        }
        return piece;
      }
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    /**
     * 测试类
     */
    public class Client {
      public static void main(String[] args) {
        Piece black = PieceFactory.getInstance().getPiece("black");
        black.put(1, 1);
        Piece black1 = PieceFactory.getInstance().getPiece("black");
        black1.put(2, 2);
        Piece white = PieceFactory.getInstance().getPiece("white");
        white.put(3, 3);
        Piece white1 = PieceFactory.getInstance().getPiece("white");
        white1.put(4, 4);
      }
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    // Make sure to add code blocks to your code group

    # 示例代码2

    场景2

    文本编辑器中字符显示,在文本编辑器中有许多字符需要显示,大部分字符是相似,如字体、大小和颜色,使用享元模式可以共享相同的字符对象,下面是一个简化的示例。

      /**
       * 字符
       * 抽象享元接口
       */
      public interface Character {
        // 显示字符
        void display();
      }
      
      1
      2
      3
      4
      5
      6
      7
      8
      /**
       * 具体字符
       * 具体享元类
       */
      @Slf4j
      public class ConcreteCharacter implements Character {
        // 字符
        private String symbol;
      
        public ConcreteCharacter(String symbol) {
          this.symbol = symbol;
        }
      
        @Override
        public void display() {
          log.info("字符:{}", symbol);
        }
      }
      
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      /**
       * 字符工厂
       * 享元工厂类
       */
      @Slf4j
      public class CharacterFactory {
        // 字符map
        private static Map<String, Character> characterMap = new HashMap<>();
      
        public static Character getCharacter(String symbol) {
          Character character = characterMap.get(symbol);
          if (character == null) {
            character = new ConcreteCharacter(symbol);
            log.info("创建字符对象");
            characterMap.put(symbol, character);
          }
          return character;
        }
      }
      
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      /**
       * 测试类
       */
      public class Client {
        public static void main(String[] args) {
          Character character = CharacterFactory.getCharacter("A");
          character.display();
          Character character2 = CharacterFactory.getCharacter("A");
          character2.display();
        }
      }
      
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      // Make sure to add code blocks to your code group
      #结构型模式#设计模式
      上次更新: 2023/11/17, 09:38:49
      桥接模式
      组合模式

      ← 桥接模式 组合模式→

      最近更新
      01
      FRP内网穿透docker部署 工具
      05-07
      02
      Office Util办公工具 工具
      01-14
      03
      Git常用命令
      01-16
      更多文章>
      Theme by Vdoing | Copyright © 2023-2025 鲁ICP备2023014898号 公安备案号:37020302372159
      • 跟随系统
      • 浅色模式
      • 深色模式
      • 阅读模式
      ×