享元模式(结构型模式)
定义
运用共享技术对对象进行复用。通过共享已经存在的对象减少创建对象的开销。
结构
- 内部状态:不随环境改变,可共享部分。
- 外部状态:随环境改变,不可共享。
- 抽象享元角色:接口或抽象类,在其中声明公共方法向外界提供对象的内部数据(内部状态),也可以设置外部数据(外部状态)。
- 具体享元角色:实现抽象享元类为内部状态提供存储空间。常结合单例模式设置具体享元类,为每个具体享元类提供唯一的对象。
- 单例模式
- 非享元角色:不是所有抽象享元类的子类都被共享,通过实例化创建非共享具体先挂类的对象。
- 享元工厂角色:负责创建和管理享元角色。客户请求享元对象时,工厂检查是否存在符合要求的享元对象,存在则提供给客户,不存在则创建新的享元对象。
举例
- 抽象享元角色
/**
* @author :yangzhipeng
* @date : 2023/3/6 11:07
* Description : 抽象享元角色
*/
public abstract class AbstratBox {
/**
* 获取图形的方法 abstract修饰内部模式的方法
*/
public abstract String getShape();
/**
* 显示图形和颜色
*/
public void display(String color){
System.out.println("方块形状" + getShape() + "颜色" + color);
}
}
- 具体享元角色
/**
* @author :yangzhipeng
* @date : 2023/3/6 11:12
* Description : I图形类(具体享元角色)
*/
public class IBox extends AbstratBox{
@Override
public String getShape() {
return "I";
}
}
public class XBox extends AbstratBox{
@Override
public String getShape() {
return "X";
}
}
-
非享元角色
-
享元工厂角色
/**
* @author :yangzhipeng
* @date : 2023/3/6 11:13
* Description : 工厂类,将该类设计为单例
*/
public class BoxFactory {
private HashMap<String,AbstratBox> map;
/**
* 单例模式-饿汉式
*/
private static BoxFactory boxFactory = new BoxFactory();
/**
* 提供一个方法获取工厂对象
*/
public static BoxFactory getInstance(){
return boxFactory;
}
/**
* 在构造方法中进行初始化
* 单例模式,构造方法私有
*/
private BoxFactory(){
map = new HashMap<String,AbstratBox>();
map.put("I",new IBox());
map.put("X",new XBox());
}
/**
* 根据名称获取图形对象
*/
public AbstratBox geShape(String name){
return map.get(name);
}
}
优点
- 极大减少内存中对象数量
- 外部状态相对独立,不影响内部状态
缺点
- 分离内部状态和外部状态,使得程序逻辑复杂
使用场景
- 有大量相同或相似的对象
- 对象的大部分状态都可以外部化
- 使用享元模式需要维护一个存储享元对象的享元池,需要耗费一定系统资源。因此,应在多次重复使用享元对象时才值得使用享元模式