结构型模式之享元模式
程序员文章站
2023-04-03 13:18:08
享元模式(Flyweight Pattern)是池技术的重要实现方式,可以降低大量重复的、细粒度的类在内存中的开销。 定义: 使用共享对象可有效地支持大量的细粒度对象。 以共享的方式高效地支持大量的细粒度对象。享元对象能做到共享的关键是区分内部状态(Internal State)和外部状态(Exte ......
享元模式(flyweight pattern)是池技术的重要实现方式,可以降低大量重复的、细粒度的类在内存中的开销。
定义:
- 使用共享对象可有效地支持大量的细粒度对象。
- 以共享的方式高效地支持大量的细粒度对象。享元对象能做到共享的关键是区分内部状态(internal state)和外部状态(external state)。
- 内部状态是存储在享元对象内部的、可以共享的信息,并且不会随环境改变而改变。
- 外部状态是随环境改变而改变且不可以共享的状态。享元对象的外部状态必须由客户端保存,并在享元对象被创建后,在需要使用的时候再传入到享元对象内部。
享元模式的类图如下所示。
享元模式具有以下4个角色:
- 抽象享元(flyweight)角色:对享元类进行抽象,需要外部状态的操作可以通过参数的形式将外部状态传入。
- 具体享元(concreteflyweight)角色:实现抽象享元定义的业务,注意享元对象的内部状态必须与环境无关,从而使得享元对象可以在系统内共享。
- 享元工厂(flyweightfactory)角色:构造一个池容器,负责创建和管理享元角色,并提供从池容器中获得对象的方法,保证享元对象可以被系统适当的共享。当一个客户端对象请求一个享元对象时,享元工厂角色会检查系统中是否已经有一个符合要求的享元对象。如果已经有了,享元工厂则提供这个已有的享元对象,否则创建一个合适的享元对象。
- 客户端角色:自行存储所有享元对象的外部状态。
flyweight.java
public interface flyweight { // 业务方法 public abstract void operation(string extrinsicstate); }
concreteflyweight.java
public class concreteflyweight implements flyweight { private string intrinsicstate;// 内部状态 public concreteflyweight(string intrinsicstate) { this.intrinsicstate = intrinsicstate; } @override public void operation(string extrinsicstate) { system.out.println("内部状态" + intrinsicstate + ",外部状态:" + extrinsicstate); } @override public string tostring() { return "内部状态=" + intrinsicstate; } }
flyweightfactory.java
public class flyweightfactory { private static map<string, flyweight> pool = new hashmap<string, flyweight>(); private flyweightfactory(){} // 私有构造方法 public static flyweight getflyweight(string intrinsicstate) { flyweight flyweight = pool.get(intrinsicstate); if (flyweight == null) { flyweight = new concreteflyweight(intrinsicstate); pool.put(intrinsicstate, flyweight); } return flyweight; } }
client.java
public class client { public static void main(string[] args) { for (int i = 0; i < 5; i++) { flyweight flyweight = flyweightfactory.getflyweight("" + i); flyweight.operation("" + (i + 1)); } flyweight flyweight = flyweightfactory.getflyweight("0"); system.out.println(flyweight); } }
优点:
- 大幅减少内存中对象的数量,降低程序内存的占用,提高性能。但是相应付出的代价也很高。
缺点:
- 享元模式增加了系统的复杂性,需要分出外部状态和内部状态,而且内部状态具有固化特性,不应该随外部状态改变而改变,使得程序逻辑复杂化。
- 享元对象将享元对象的状态外部化,而读取外部状态使得运行时间变长。
使用场景:
- 系统中有大量相似对象,这些对象耗费大量内存。
- 细粒度的对象都具备较接近的外部状态,而且内部状态与环境无关,即对象没有特定身份。
- 需要缓冲池的场景。
摘自:
青岛东合信息技术有限公司 . 设计模式(java版) . 电子工业出版社,2012,103-105.
上一篇: 一个小白的四次前端面试经历
下一篇: 行为型模式之命令模式