- 享元模式(蝇量模式)
该模式是对象的结构模式。享元模式主要功能是以共享的方式高效地支持大量的细粒度对象。从而实现这些细粒度对象的复用,这样系统就可以使用少量的比较相似的状态变化小的对象,从而实现对象复用。在这种情况下就要求共享的对象必须是细粒度的对象。享元模式一般分为两类单纯的享元模式和复合的享元模式。如果要区分单纯享元模式和复合享元模式,这里要介绍下内部状态和外部状态。
内部状态:在享元内部对象内不随外界环境而改变的共享部分。
外部状态:随着环境改变而改变,不能够共享的状态就是外部状态。
由内部状态和外部状态的定义可以看出,内部状态是存储于对象内部的,外部状态则应该有客户端来考虑。 - 享元状态的示例图
- 享元模式包含角色
- 抽象享元角色:一般是接口或者是抽象类,给出具体享元角色需要实现的方法。这些方法既可以分享内部状态的数据,也可以调用这些方法修改外部状态。
- 具体享元角色:实现抽象享元角色的方法,为内部状态增加存储空间。
- 非具体共享享元角色:指出那些不需要共享的Flyweight子类;是不可共享的外部状态,它以参数的形式注入具体享元的相关方法中。
- 享元工厂角色:享元模式中最为重要的角色。一般具有创建并且管理享元类的功能,并且能确保享元对象被系统适当的共享,当一个客户对象调用一个享元对象的时候,享元工厂角色会检查系统中是否已经存在一个已经符合要求的享元对象,如果已经又饿,享元工厂则不需要在创建另一个相同的新的对象,只需要提供已有的即可,如果没有,则需要创建一个新的对象,提供给到系统使用。
- 示例代码
数据库的链接池为例。
- 抽象享元角色
public interface DataBaseConnPool {
void use();
}
- 具体享元角色:
public class MySqlConnPool implements DataBaseConnPool {
@Override
public void use() {
System.out.println(">>>>>>>>这是一个MySql数据库链接池。。。。");
}
}
public class SqlSeverConnPool implements DataBaseConnPool {
@Override
public void use() {
System.out.println(">>>>>>>这是一个SqlSever数据库链接池。。。。。");
}
}
- 享元工厂角色
public class ConnPoolFactory {
private static final HashMap<String,DataBaseConnPool> hashMap = new HashMap<>();
public static DataBaseConnPool getPool(String name,int type){
DataBaseConnPool dataBaseConnPool = hashMap.get(name);
if (dataBaseConnPool == null){
if (type == 0) {
dataBaseConnPool = new SqlSeverConnPool();
hashMap.put("sqlSever", dataBaseConnPool);
}else {
dataBaseConnPool = new MySqlConnPool();
hashMap.put("MySql", dataBaseConnPool);
}
}
return dataBaseConnPool;
}
//获得对象数量总数
public static int getCount() {
return hashMap.size();
}
}
- 测试代码:
public class Main {
public static void main(String[] args) {
DataBaseConnPool dataBaseConnPool = ConnPoolFactory.getPool("",0);
dataBaseConnPool.use();
DataBaseConnPool dataBaseConnPool1 = ConnPoolFactory.getPool("",1);
dataBaseConnPool1.use();
DataBaseConnPool dataBaseConnPool2 = ConnPoolFactory.getPool("",1);
dataBaseConnPool2.use();
System.out.println("本次运行创建新对象的数量为:"+ConnPoolFactory.getCount());
}
}
- 运行结果截图:
- 享元模式的优缺点
-
优点:
可以减少系统创建对象,减少系统中的对象的个数。降低系统的内存占用率,提高使用效率。 -
缺点:
享元模式的缺点通过以上代码也可以看出,就是增加了系统的复杂度。