欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 文旅 > 明星 > 能省一点是一点 - 享元模式(Flyweight Pattern)

能省一点是一点 - 享元模式(Flyweight Pattern)

2025/10/1 1:46:05 来源:https://blog.csdn.net/Zongkunxue/article/details/144753754  浏览:    关键词:能省一点是一点 - 享元模式(Flyweight Pattern)

享元模式(Flyweight Pattern)

  • 享元模式(Flyweight Pattern)
    • 享元模式(Flyweight Pattern)概述
      • 享元模式包含的角色:
      • 享元模式应用场景
    • talk is cheap, show you my code
    • 总结

享元模式(Flyweight Pattern)

享元模式(Flyweight Pattern)是一种结构型设计模式,它主要用于减少创建大量细粒度对象所带来的内存占用问题。通过共享尽可能多的对象,即所谓的“享元”,来减少内存使用量和提高性能。这种设计模式特别适合于需要大量创建相同对象的情况。而且不要被享元这个名称迷惑,Flyweight的意思是轻量级的意思,更多的意思,这个模式是想告诉共享内存对象这个意思。

为什么会有这种设计模式
比如,当我们要构建的系统中有大量基本一样的元素的时候。
在这里插入图片描述
小时候我们玩过的像素风的游戏,大家可以看到实际上里面的各种场景就是有大量的基础元素拼装出来的。有很多完全一样的像素块,那对这些像素块,我们不需要每次用的时候都创建新的像素块对象。因为新建新的对象,需要消耗堆内存,而且这种消耗是没有意义的。

享元模式(Flyweight Pattern)概述

当一个软件需要创建大量的对象的时候,就会导致内存消耗过多,系统性能下降。而享元模式就是为了解决这个问题而出现的设计模式。

享元模式(Flyweight Pattern)的核心思想: 如果一个对象实例创建之后不可变的话,反复创建这种实例就变得没有必要,直接向客户端返回一个共享的实例就可以了,这样既节省了内存,还避免了创建对象的过程,提升运行效率。

享元模式包含的角色:

享元模式主要包含以下四种角色

  • 抽象享元(Flyweight)角色:是所有的具体享元类的基类,为具体享元规范需要实现的公共接口,非享元的外部状态以参数的形式通过方法传入。
  • 具体享元(Concrete Flyweight)角色:实现抽象享元角色中所规定的接口。
  • 非享元(Unsharable Flyweight)角色:是不可以共享的外部状态,它以参数的形式注入具体享元的相关方法中。
  • 享元工厂(Flyweight Factory)角色:负责创建和管理享元角色。当客户对象请求一个享元对象时,享元工厂检查系统中是否存在符合要求的享元对象,如果存在则提供给客户;如果不存在的话,则创建一个新的享元对象。
    在这里插入图片描述

享元模式应用场景

应用场景其实是围绕着享元模式的核心设计思想,减少对象的创建展开的。大致有下面几种:

  1. 软件设计中有大量相似的对象
  2. 缓存场景
  3. 需要多次重复使用某一个对象的时候

talk is cheap, show you my code

在这里插入图片描述
我们设计围棋的时候,会发现,白棋和黑棋会有很多,但是它们都是一样的。所以我们通过利用享元模式来设计创建围棋中的棋子。

围棋棋子 Go chess pieces

public class GoChessPiecesFactory {public static Map<String, AbstractGoChessPieces> map = new HashMap<>();public static AbstractGoChessPieces getAbstractGoChessPieces(String color) {if (map.containsKey(color)) {return map.get(color);}else {if (color.equals("black")) {AbstractGoChessPieces black = new BlackGoChessPieces();map.put("black", black);}if (color.equals("white")) {AbstractGoChessPieces white = new WhiteGoChessPieces();map.put("white", white);}}return map.getOrDefault(color, null);}
}
abstract class  AbstractGoChessPieces {String color;public abstract void display();}class BlackGoChessPieces extends AbstractGoChessPieces {@Overridepublic void display() {System.out.println("black");}
}class WhiteGoChessPieces extends AbstractGoChessPieces {@Overridepublic void display() {System.out.println("white");}
}public class Test4 {public static void main(String[] args) {AbstractGoChessPieces black = GoChessPiecesFactory.getAbstractGoChessPieces("black");AbstractGoChessPieces black1 = GoChessPiecesFactory.getAbstractGoChessPieces("black");AbstractGoChessPieces black2 = GoChessPiecesFactory.getAbstractGoChessPieces("black");AbstractGoChessPieces white = GoChessPiecesFactory.getAbstractGoChessPieces("white");AbstractGoChessPieces white1 = GoChessPiecesFactory.getAbstractGoChessPieces("white");System.out.println(black == black1);System.out.println(black1 == black2);System.out.println(white == white1);black.display();white.display();}}

输出结果

true
true
true
black
white

代码解释:

  1. AbstractGoChessPieces 抽象类 : 定义了一个抽象类 AbstractGoChessPieces,表示围棋棋子的基本属性和行为。
  2. BlackGoChessPieces 类 :继承自 AbstractGoChessPieces,表示黑色棋子。
  3. WhiteGoChessPieces 类 : 继承自 AbstractGoChessPieces,表示白色棋子。
  4. GoChessPiecesFactory 类 :工厂类 GoChessPiecesFactory 负责创建并缓存 AbstractGoChessPieces 的实例。

总结

当代码实现中出现大量相同对象的时候,我们就可以考虑使用享元模式。这种设计模式通过共享对象,节约了内存空间,提升了系统性能。
优点:

  1. 减少内存中的对象数量
  2. 享元模式外部状态不影响内部状态
    缺点:
  3. 享元模式需要隔离出内外两种状态,会使得代码逻辑变得复杂一点

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词