8

初识设计模式 - 享元模式 - 程序员翔仔

 1 year ago
source link: https://www.cnblogs.com/fatedeity/p/16783274.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

初识设计模式 - 享元模式

古代的活字印刷术就有点像享元模式,活字印刷就是将每个字模做出来,再印刷时再选取需要的字模到印刷板上,这样就构成了一页书的印刷板。这样的活字印刷大大提升了效率,减少了印刷板的空间。

在享元模式中,存储共享实例对象的地方称为享元池(Flyweight Pool)。类比到上述的活字印刷术中,放置字模的地方就是享元池。

享元模式能做到共享的关键是区分了内部状态和外部状态,它们的简单释义是:

  • 内部状态:存储在享元对象内部且不跟随环境变化而改变的状态,内部状态可以在对象之间共享
  • 外部状态:通常由客户端保存,当需要时再传入享元对象中的状态,会跟随环境变化而改变,不可以在对象之间共享。

一个典型的享元工厂类的代码示例如下:

public class FlyweightFactory { // 使用 HashMap 定义享元池 private final HashMap<String, Flyweight> flyweights = new HashMap<>(); public Flyweight getFlyweight(String key) { // 如果对象存在,直接从享元池中获取 if (flyweights.containsKey(key)) { return (Flyweight) flyweights.get(key); } else { // 如果对象不存在,先创建一个新的对象添加到享元池中,然后返回 Flyweight fw = new ConcreteFlyweight(); flyweights.put(key, fw); return fw; } }}

一个典型的享元抽象类的代码示例如下:

public abstract class Flyweight { // 内部状态作为成员对象,同一个享元对象其内部状态是一致的 protected Object intrinsicState; public Flyweight(Object intrinsicState) { this.intrinsicState = intrinsicState; } public void operation(Object extrinsicState) { // 外部状态在使用时由外部提供,每一次都可以不同 }}

通常,实际会根据业务情况定义具体享元类,代码示例如下:

public class ConcreteFlyweight extends Flyweight { public ConcreteFlyweight(Object intrinsicState) { super(intrinsicState); } @Override public void operation(Object extrinsicState) { // 结合内部状态 intrinsicState 以及方法参数传入的 extrinsicState 完成具体逻辑 }}

享元模式的主要优点如下:

  • 极大地减少内存中对象的数量,节约了系统资源,提高了系统性能
  • 享元模式的外部状态相对独立,而且不会影响其内部状态,从而使得享元对象可以在不同的环境中被共享

享元模式的主要缺点如下:

  • 享元模式需要分离出内部状态和外部状态,从而使得系统变得复杂,这使得程序的逻辑复杂化
  • 为了使对象可以共享,享元对象需要将部分状态外部化,而读取外部状态将使得运行时间变长

享元模式的适用场景如下:

  • 一个系统有大量相同或相似的对象,造成内存大量耗费

在 Java 类库中的 String 类就使用了享元模式,使用字面量创建的对象是共享的,而不会重新为此分配内存空间。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK