享元模式:就是共享技术,对于系统中存在大量相同的对象,把他们抽取成一个对象放在缓存中进行使用,这样可以大大节省系统资源。
例如:围棋棋盘上有两种棋子,一个是黑子、一个是白子,如果在下棋的时候每下一个棋子就要new一个棋子对象,那么就会有大量的棋子对象,如果我们只new两个棋子对象,一个白子一个黑子,在使用的时候就用这两个对象就可以了。那么这个时候就有人问位置不一样怎么办,那么我们给棋子提供一个位置信息就可以了。
棋子位置(外部信息)
public class Location {
private int x;
private int y;
public Location(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 interface Chess {
String getColor();
void show(Location location);
}
具体棋子
public class ChessPieces implements Chess {
private String color;
public ChessPieces(String color) {
this.color = color;
}
@Override
public String getColor() {
return color;
}
@Override
public void show(Location location) {
System.out.println(color + "棋子位置:[" + location.getX() + "," + location.getY() + "]");
}
}
享元工厂
public class ChessFactory {
private static Map<String, Chess> map = new HashMap<>();
public static Chess getChess(String color) {
if (!map.containsKey(color)) {
map.put(color, new ChessPieces(color));
}
return map.get(color);
}
}
客户端
public class Client {
public static void main(String[] args) {
Chess chess1 = ChessFactory.getChess("黑色");
Chess chess2 = ChessFactory.getChess("黑色");
/**
* true
* 黑色棋子位置:[1,1]
* 黑色棋子位置:[1,2]
*/
System.out.println(chess1 == chess2);
chess1.show(new Location(1, 1));
chess1.show(new Location(1, 2));
}
}
优缺点
优点:大大减少了对象的创建,降低了程序内存的占用,提高效率
缺点:提高了系统的复杂度。需要分离出内部状态和外部状态,而外部状态具有固化特性,不应该随着内部状态的改变而改变
使用场景:系统中存在大量相似对象、需要缓冲池的场景
源码查看
对于Integer对象 -128到127 是有个缓存的,查看Integer类829行
这里就是用数组来进行缓存的