设计模式:享元模式
享元模式中的享指的共享的意思,该模式以共享的方式支持某些对象的重用(特别是一些大的对象)以此节约空间。典型的是以时间换空间的做法。
例如:java语言中String类型就是使用享元模式。对于JVM来说,String对象都是共享的。如果一个系统中两个String对象所包含的字符串内容相同,jvm
实际上只创建一个String对象提供两个引用。
享元模式一般的角色:
享元工厂类(FlyWeight享元工厂类):管理享元对象
抽象享元类(FlyWeight抽象类):接口或抽象类,向外界提供对象内部状态。
具体享元类(ConcreteFlyWeight):继承自抽象享元类。为内部状态提供成员变量存储。
非共享享元类(UnshareConcreteFlyWeight):不能被共享的一些子类。
享元对象能作为共享的的关键是区分内部状态和外部状态。
内部状态:可以共享。
外部状态:不可以共享。
例子:
描述一个围棋软件,每个棋子是一个对象(颜色,形状等)这些是可以共享的,对应内部状态。只有棋子的位置不是共享的,对应外部状态。
/**
* 享元类
*/
public interface ChessFlyWeight {
//颜色
void setColor(String c);
String getColor();
//描述位置
void display(Position c);
}
class OneChess implements ChessFlyWeight{
//为内部状态提供成员变量存储。
private String color;
public OneChess(String color) {
super();
this.color = color;
}
@Override
public void display(Position c) {
System.out.println("棋子颜色:"+color);
System.out.println("棋子位置:"+c.getX()+"----"+c.getY());
}
@Override
public String getColor() {
return color;
}
@Override
public void setColor(String c) {
this.color = c;
}
}
外部状态位置单独设计一个类
/**
* 外部状态UnSharedConcreteFlyWeight
* 非共享狀態
*/
public class Position {
private int x;
private int y;
public Position(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;
}
}
享元工厂类
/**
* 享元工厂类
* 创建和管理享元对象
*/
public class ChessFlyWeightFactory {
//享元池
private static Map<String,ChessFlyWeight> map = new HashMap<String, ChessFlyWeight>();
public static ChessFlyWeight getChess(String color){
if(map.get(color)!=null){
return map.get(color);
}else{
ChessFlyWeight cfw = new OneChess(color);
map.put(color, cfw);
return cfw;
}
}
}
public class Client {
public static void main(String[] args) {
ChessFlyWeight chess1 = ChessFlyWeightFactory.getChess("黑色");
ChessFlyWeight chess2 = ChessFlyWeightFactory.getChess("黑色");
System.out.println(chess1 == chess2);
System.out.println("增加位置外部状态");
chess1.display(new Position(1, 12));
chess2.display(new Position(50, 60));
}
}

使用享元模式一般步骤:
1. 抽象享元对象,内部状态采用享元类处理
2. 外部状态(可变状态,非共享)单独抽取类处理
3. 设计享元工厂类,采用对象池管理享元对象。
一般使用场景是对象池,将对象缓存。极大减少内存中对象的数量相同或相似对象内存中只存一份,极大的节约资源,提高系统性能

浙公网安备 33010602011771号