设计模式
享元模式
享元模式又称为轻量级模式,它是一种对象结构型模式,因为享元模式要求能够共享的对象必须是细粒度对象。享元模式是对象池的一种实现,实质就是缓存共享对象,降低内存消耗。
最常见的例子就是五子棋,在五子棋中棋子分为黑白两种颜色,这就是内部状态,不可改变。而双方落子的位置是动态变化的,所以棋子的坐标就是外部状态。使用享元模式,只需要黑白两个对象,大大减少了内存的消耗。
抽象享元角色Gobang
package com.wangscaler.flyweight;
/**
* @author wangscaler
* @date 2021.06.29 18:12
*/
public abstract class Gobang {
protected int x;
protected int y;
protected String chess;
public Gobang(String chess) {
this.chess = chess;
}
public abstract void point(int x, int y);
public void printPoint() {
System.out.println(this.chess + "(" + this.x + "," + this.y + ")");
}
}
复制代码
具体享元角色Black,实现了point方法
package com.wangscaler.flyweight;
/**
* @author wangscaler
* @date 2021.06.29 18:12
*/
public class Black extends Gobang {
public Black() {
super("黑子");
}
@Override
public void point(int x, int y) {
this.x = x;
this.y = y;
printPoint();
}
}
复制代码
具体享元角色White
package com.wangscaler.flyweight;
/**
* @author wangscaler
* @date 2021.06.29 18:12
*/
public class White extends Gobang {
public White() {
super("白子");
}
@Override
public void point(int x, int y) {
this.x = x;
this.y = y;
printPoint();
}
}
复制代码
享元工厂角色GobangFactory,获取黑棋白棋,没有则初始化,有则直接提供
package com.wangscaler.flyweight;
import java.util.HashMap;
/**
* @author wangscaler
* @date 2021.06.29 18:12
*/
public class GobangFactory {
private static GobangFactory gobangFactory = new GobangFactory();
private final HashMap<String, Gobang> cache = new HashMap<String, Gobang>();
private GobangFactory() {
}
public static GobangFactory getInstance() {
return gobangFactory;
}
public Gobang getChessmanObject(String type) {
if (!cache.containsKey(type)) {
if (type.equals("B")) {
cache.put(type, new Black());
} else if (type.equals("W")) {
cache.put(type, new White());
} else {
System.out.println("棋子类型不正确");
}
}
return cache.get(type);
}
public void getCount() {
System.out.println("当前hashmap的个数" + cache.size());
}
}
复制代码
main
package com.wangscaler.flyweight;
import java.util.Random;
/**
* @author wangscaler
* @date 2021.06.29 18:12
*/
public class Flyweight {
public static void main(String[] args) {
GobangFactory gobangFactory = GobangFactory.getInstance();
Random random = new Random();
Gobang gobang = null;
for (int i = 0; i < 10; i++) {
if (i % 2 == 0) {
gobang = gobangFactory.getChessmanObject("B");
} else {
gobang = gobangFactory.getChessmanObject("W");
}
if (gobang != null) {
gobang.point(i, random.nextInt(15));
gobangFactory.getCount();
}
}
}
}
复制代码
源码中的享元模式
JAVA 中的 Integer,这个之前的文章Java易错点2已经写过了,就不再赘述。
总结
享元模式,顾名思义享就是共享,元就是对象,即共享对象的模式。
享元模式的角色:
- 抽象享元角色:是所有的具体享元类的基类即产品的抽象类,定义出对象的外部状态(不可共享的状态,可以改变)和内部状态(不会随着环境的变化而变化),非享元的外部状态以参数的形式通过方法传入。
- 具体享元角色:即具体的产品对象,实现抽象享元角色中所规定的接口。
- 非享元角色:是不可以共享的外部状态。一般不会出现在享元工厂中。
- 享元工厂角色:负责创建和管理享元角色。当客户请求一个享元对象时,享元工厂检査系统中是否已经存在符合要求的享元对象,如果不存在则创建一个;如果存在,则直接提供。
使用场景:
1、有很多对象,且对象的状态可以外部化。
2、用标识码标识对象(像五子棋中的W和B、Integer中的-127到128),如果内存中有,直接取出来,没有则初始化。
3、享元模式的本质是分离与共享 : 分离变与不变,并且共享不变。实现对象的复用
参考资料
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END