享元模式概念:
运用共享技术,有效的支持大量细粒度的对象的复用.
享元模式能够做到共享的关键是区分了内部状态和外部状态:
内部状态:可以共享,不会随环境的变化而变化。
外部状态:不可以共享,会随环境的变化而变化。
享元模式的优点:
1.极大的减少了内存中对象的数量。
2.相同或者相似的对象,内存中只有一份,节约资源,提升效率.
3.外部状态相对独立,不会影响内部状态。
享元模式的缺点:
1.模式复杂,使程序复杂化。
享元模式的角色:
1.抽象享元角色:通常是一个接口或者抽象类,抽象出具体享元角色的业务方法,可以提供内部状态也可以注入外部状态。
2.具体享元角色:实现抽象享元角色的业务方法,为内部状态提供成员变量进行存储。
3.非共享具体享元角色:实现抽象享元角色的业务方法,但是不可以共享,需要时直接创建。
4.享元工厂类:创建并管理享元对象。
下面我们以围棋的棋子为例(因为围棋的棋子大家都知道为黑白两种,而黑色的每个棋子,棋子颜色,形状,大小一样,只是摆放在棋盘上的坐标位置不同(白色也一样))
/**
*抽象享元角色
* Created by Administrator
*/
public interface PieceFlyweight {
void setColor();
String getColor();
//注入外部状态
void Display(PiecePosition p);
}
/**
*具体享元角色
* Created by Administrator
*/
public class ConcretPiece implements PieceFlyweight{
private String color;
public ConcretPiece(String color) {
this.color = color;
}
@Override
public void setColor() {
}
@Override
public String getColor() {
return null;
}
@Override
public void Display(PiecePosition p) {
Log.d("Piece","棋子颜色="+color);
Log.d("Piece","棋子x坐标="+p.getX()+" 棋子y坐标="+p.getY());
}
}
/**
*外部状态
* Created by Administrator
*/
public class PiecePosition {
private int x,y;
public PiecePosition(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;
}
}
/**
*享元工厂
* Created by Administrator
*/
public class PieceFlyweightFactory {
private static Map<String,PieceFlyweight> pieceMap=new HashMap<String,PieceFlyweight>();
public static PieceFlyweight getPiece(String color){
if(pieceMap.containsKey(color)){
return pieceMap.get(color);
}else{
PieceFlyweight pieceFlyweight=new ConcretPiece(color);
pieceMap.put(color,pieceFlyweight);
return pieceFlyweight;
}
}
}
//调用(结果可以看到,我们第一次调用白色,没有就创建,第二次调用,有,直接返回,两个棋子,是同一个对象,颜色相同,坐标位置不同)
PieceFlyweight piece1 = PieceFlyweightFactory.getPiece("白色");
PieceFlyweight piece2 = PieceFlyweightFactory.getPiece("白色");
Log.d("Piece","piece1="+piece1);
Log.d("Piece","piece2="+piece2);
piece1.Display(new PiecePosition(10,20));
piece2.Display(new PiecePosition(20,30));
结果: