享元模式

发布时间: 更新时间: 总字数:926 阅读时间:2m 作者: IP属地: 分享 复制网址

Use sharing to support large numbers of fine-grained objects efficiently.(使用共享对象可以有效的支持大量的细粒度的对象。)

享元模式介绍

享元模式乃是池技术中的重要实现方式。核心是重复利用对象。

由定义可知两个要求:细粒度的对象和共享对象。先了解一下对象的外部状态以及内部状态,细粒度对象不可避免会使对象数量多且性质相近,那我们就将这些对象分为两部分,也就是外部状态和内部状态。下面解释一下内部状态与外部状态:

  • 外部状态:就是对象得以依赖的一个标记,随环境的改变而改变,不可以共享的状态,比如说用户名以及ID之类的信息。
  • 内部状态:就是对象可以共享出来的信息,存储在享元对象内部并且不会随环境的改变而改变,不必存储在具体某个对象中,属于可以共享的部分。

类图如下:

flyweight

享元模式分析

优点:

  • 减少应用程序创建的对象。
  • 降低程序内存占用。
  • 增强程序性能。

缺点:

  • 提高了系统复杂性。
  • 需要分离出外部状态和内部状态。

享元模式之实现

Golang

Java

首先是抽象享元角色:

public abstract class Flyweight{
    //内部状态
    private String intrinsic;
    //外部状态
    protected final String Extrinsic;
    //要求享元角色必须接受外部状态
    public Flyweight(String extr){
        this.Extrinsic = extr;
    }
    //定义业务操作
    public abstract void operate();

    //内部状态的getter/setter
    public String getIntrinsic(){
        return intrinsic;
    }

    public void setIntrinsic(String intrinsic)
    {
        this.intrinsic = intrinsic;
    }
}

抽象享元角色一般为抽象类,在实际项目中,一般是一个实现类,它是描述一类事物的方法,在抽象角色中,一般需要把外部状态和内部状态定义出来,避免子类随意扩展,下面是具体的享元角色实现的代码:

public class ConcreteFlyweight extends Flyweight{
    //接受外部状态
    public ConcreteFlyweight(String extri){
        super(extri);
    }
    //根据外部状态进行逻辑处理
    public void operate(){
        //业务逻辑
    }
}

这就是实现自己的业务逻辑,然后接收外部的状态,以便内部业务逻辑对外部状态的依赖,在抽象享元中加入final关键字也是有原因的,为了防止无意见修改导致池的混乱。

下面是享元工厂:

public FlyweightFactory{
    //定义容器
    private static HashMap<String, Flyweight> pool = new HashMap<>();
    //享元工厂
    public static Flyweight getFlyweight(String extri){
        //需要返回的对象
        Flyweight flyweight = null;
        //判断是否在池中有该对象
        if(pool.containskey(extri)) {
            flyweight = pool.get(extri);
        } else {
            //根据外部状态创建享元对象
            flyweight = new ConcreteFlyweight(extri);
            pool.put(extri, flyweight);
        }
        return flyweight;
    }
}

享元模式之使用场景

当遇到以下情况时,就使用我吧,效果那是杠杠的:

  • 一个应用程序使用了大量的对象。
  • 完全由于使用大量对象造成很大的存储开销。
  • 对象的大多状态都是外部状态。
  • 如果删除对象的外部状态,那么可以用相对较少的共享对象取代很多组对象。
  • 应用程序不依赖于对象的标识。
Home Archives Categories Tags Statistics
本文总阅读量 次 本站总访问量 次 本站总访客数