享元模式

享元模式属于结构型模式,又叫轻量级模式

定义:运用共享技术有效地支持大量细粒度对象的复用。系统只使用少量的对象,而这些对象都很相似,状态变化很小,可以实现对象的多次复用。

主要用来减少对象的创建,用来减少内存和提高性能,比较常见的连接池,缓冲池这类的池技术都是享元模式

享元模式的两种状态

  1. 内部状态:在享元对象内部不随外界环境改变而改变的共享部分
  2. 外部状态:随着环境的改变而改变,不能够共享的状态就是外部状态

模式类图

角色:

  1. 抽象享元角色:Flyweight产品的抽象类,用来定义对象的外部状态和内部状态
  2. 具体享元角色:ConcreteFlyweightunshareConcreteFlyweight
  3. 享元工厂:FlyweightFactory用于构造一个池容器,提供从容器中获取对象的方法

优点

减少对象的创建,降低内存的占用,增强性能

缺点

使用享元模式使程序逻辑变得更复杂

模式代码实现

源码地址:https://github.com/mingyuHub/design-patterns

抽象享元角色
/**
 * @author: chenmingyu
 * @date: 2019/4/1 17:32
 * @description: 抽象享元角色
 */
public interface Flyweight {

    /**
     * 学习
     * @param user
     */
    void study(String user);
}
具体享元角色
/**
 * @author: chenmingyu
 * @date: 2019/4/1 17:40
 * @description: 具体享元角色
 */
public class ConcreteFlyweight implements Flyweight {

    /**
     * 内部状态
     */
    private String interiorState;

    public ConcreteFlyweight(String interiorState) {
        this.interiorState = interiorState;
    }

    @Override
    public void study(String user) {
        System.out.println(user+"学习"+interiorState+"课程");
    }
}
享元工厂
/**
 * @author: chenmingyu
 * @date: 2019/4/1 18:05
 * @description:
 */
public class FlyweightFactory {

    private static final Map<String,ConcreteFlyweight> FLYWEIGHTMAP = new HashMap<>(16);

    /**
     * 获取ConcreteFlyweight
     * @param s
     * @return
     */
    public static Flyweight getFlyweight(String s){
        ConcreteFlyweight flyweight = FLYWEIGHTMAP.get(s);
        if(null == flyweight){
            flyweight = new ConcreteFlyweight(s);
            FLYWEIGHTMAP.put(s,flyweight);
        }
        return flyweight;
    }

    /**
     * 获取FLYWEIGHTMAP数量
     * @return
     */
    public static int getFlyweightSize() {
        return FLYWEIGHTMAP.size();
    }
}
验证
public static void main(String[] args) {

    Flyweight javaFlyweight = FlyweightFactory.getFlyweight("java");
    javaFlyweight.study("a");

    Flyweight goFlyweight = FlyweightFactory.getFlyweight("go");
    goFlyweight.study("b");

    Flyweight javaFlyweight1 = FlyweightFactory.getFlyweight("java");
    javaFlyweight1.study("c");

    System.out.println(javaFlyweight == javaFlyweight1);
    System.out.println("Flyweight 总数:"+FlyweightFactory.getFlyweightSize());
}

输出

a学习java课程
b学习go课程
c学习java课程
true
Flyweight 总数:2

javago就是内部状态,不会随着外界环境改变而改变,是共享部分,而外部状态abc则由环境决定,是共享模式中的不可变部分

参考:设计模式之禅:https://www.kancloud.cn/sstd521/design/193614

推荐阅读:23种设计模式详解