定义
将系统中细粒度的相同的或者相似的对象以共享的方式存放在享元池中供客户端使用。
结构图
角色与理解
- 享元模式共分为四种角色:
-
- Flyweight(抽象享元类):通常是一个接口或者是抽象类,在抽象享元类中声明了共享享元类的公共方法,通过这些方法可以访问享元类的内部数据(内部状态),也可以设置享元类的外部数据(外部状态)
- Concrete Flyweight(共享具体享元类):实现抽象享元类,其实例称为享元对象,一般为单例模式,提供唯一的享元对象
- UnsharedConcrete Flyweight(非共享具体享元类):实现抽象享元类,但是不共享,通过构造函数进行实例化
- Flyweight Factory(享元工厂类):创建并管理享元对象,以内部的键值对结构存储享元对象
- 共享具体享元类与非共享具体享元类实现抽象享元类,能够保证他们对外具有一致的行为接口,为客户端的使用提供了便利,客户端通过享元工厂类获取共享享元对象。
- 享元工厂类返回的享元对象都是只有内部状态的享元对象,通过客户端操作添加外部状态
核心代码
抽象享元类
public abstract class Flyweight {
public void display(Color color) {
System.out.println("棋子的颜色为:" + color.getColor());
}
}
共享具体享元类
public class ConcreteFlyweight extends Flyweight {
}
享元工厂类
public class FlyweightFactory {
private static FlyweightFactory flyweightFactory = new FlyweightFactory();
private HashMap<String, Flyweight> map = new HashMap<>();
public FlyweightFactory() {
map.put("c", new ConcreteFlyweight());
}
/**
* 饿汉式加载返回工厂实例
*
* @return
*/
public static FlyweightFactory getInstance() {
return flyweightFactory;
}
public Flyweight getFlyweight(String key) {
return map.get(key);
}
}
外部状态类
@NoArgsConstructor
@AllArgsConstructor
@Getter
@Setter
public class Color {
private String color;
}
客户端
public class Client {
public static void main(String[] args) {
FlyweightFactory flyweightFactory = FlyweightFactory.getInstance();
// 获取三颗棋子
Flyweight c1 = flyweightFactory.getFlyweight("c");
Flyweight c2 = flyweightFactory.getFlyweight("c");
Flyweight c3 = flyweightFactory.getFlyweight("c");
// 判断三颗棋子是否是同一个对象
System.out.println(c1 == c2);
System.out.println(c1 == c3);
// 给棋子添加外部状态
c1.display(new Color("白色"));
c1.display(new Color("黑色"));
}
}