享元模式 (flyweight )
场景:
– 内存属于稀缺资源,不要随便浪费。如果有很多个完全相同或相似的
对象,我们可以通过享元模式,节省内存。
• 核心:
– 享元模式以共享的方式高效地支持大量细粒度对象的重用。
– 享元对象能做到共享的关键是区分了内部状态和外部状态。
• 内部状态:可以共享,不会随环境变化而改变
• 外部状态:不可以共享,会随环境变化而改变
比如说,在围棋软件中,每个棋子都是一个对象
有如下的属性
颜色
形状
大小
这三个是可以共享的(内部状态)
位置 这是不共享的(外部状态)
package com.xiaoqiang.gof23.structureModel.flyweight;
/**
* @author xiaoqiang
* @date $(DATE)-$(TIME)
*
* 享元类
*/
public interface ChessFlyWeight {
void setColor(String color);
String getColor();
void display(Coordinate c);
}
class ConcreteChess implements ChessFlyWeight {
// 为被共享的 内部状态提供成员变量提供存储 比如说棋子的颜色大小形状等
// 不能被共享的内容,设置为非共享的享元类 如 棋子的坐标位置 Coordinate
private String color;
public ConcreteChess(String color) {
this.color = color;
}
@Override
public void setColor(String color) {
this.color = color;
}
@Override
public String getColor() {
return color;
}
@Override
public void display(Coordinate c) {
System.out.println("棋子颜色:" + color + "棋子位置" + c.getX() + "---" + c.getY());
}
}
享元工厂
package com.xiaoqiang.gof23.structureModel.flyweight;
import java.util.HashMap;
import java.util.Map;
/**
* @author xiaoqiang
* @date $(DATE)-$(TIME)
*/
public class ChessFlyWeightFactory {
//享元池
private static Map<String, ChessFlyWeight> map = new HashMap<>();
public static ChessFlyWeight getChess(String color) {
// 如果没有之前此颜色 创建 ,有就从 享元池里面拿
if (map.get(color) != null) {
return map.get(color);
} else {
ChessFlyWeight cwf = new ConcreteChess(color);
map.put(color, cwf);
return cwf;
}
}
}
外部状态的 非享元类 位置坐标
package com.xiaoqiang.gof23.structureModel.flyweight;
/**
* @author xiaoqiang
* @date $(DATE)-$(TIME)
*
* 外部类
*
*
* 位置坐标
*/
public class Coordinate {
private int x;
private int y;
public Coordinate(int x, int y) {
this.x = x;
this.y = y;
}
public int getX() {
return x;
}
public void setX(int x) {
this.x = x;
}
public int getY() {
return y;
}
public void setY(int y) {
this.y = y;
}
}
Client类
package com.xiaoqiang.gof23.structureModel.flyweight;
/**
* @author xiaoqiang
* @date $(DATE)-$(TIME)
*/
public class Client {
public static void main(String[] args) {
ChessFlyWeight chess = ChessFlyWeightFactory.getChess("黑色");
ChessFlyWeight chess1 = ChessFlyWeightFactory.getChess("黑色");
// 共享同一个黑色棋子
System.out.println(chess);
System.out.println(chess1);
// 但外部状态不一样
System.out.println("外部状态的处理");
chess.display(new Coordinate(10, 10));
chess.display(new Coordinate(20, 20));
}
}