模式概述:
它摒弃了在每个对象中保存所有数据的方式, 通过共享多个对象所共有的相同状态, 让你能在有限的内存容量中载入更多对象。
使用场景:
1.仅在程序必须支持大量对象且没有足够的内存容量时使用享元模式。
代码样例:
代码背景: 下围棋,棋手每走一步,需要创建一个棋子对象;这些大量棋子对象非常相似;其中坐标(外在状态)是每个棋子都不相同的;样式(内在状态),如颜色、形状、大小基本都是相同重复的。使用享元模式解决每创建一个棋子就创建一个对应样式而造成浪费资源的问题(大量重复样式对象)。把样式对象进行共享。
/**
* 棋子(除了坐标不同外,外观相关属性是固定的,针对外观使用享元)
*/
public class Chess {
private int x;
private int y;
private Style style;
public Chess(int x, int y, Style style) {
this.x = x;
this.y = y;
this.style = style;
}
public Style getStyle() {
return style;
}
}
/**
* 棋子样式(享元对象)
*/
public class Style {
private String color;
private String shape;
private int length;
private int weight;
public Style(String color,String shape,int length,int weight){
this.color = color;
this.shape = shape;
this.length = length;
this.weight = weight;
}
}
/**
* 享元工厂,实现对象的共享
*/
public class StyleFactory {
Map<String,Style> styles = new HashMap();
private String defaultShape;
private int defaultLength;
private int defaultWeigth;
public StyleFactory(String shape,int length,int weigth){
this.defaultShape = shape;
this.defaultLength = length;
this.defaultWeigth = weigth;
}
/**
* 创建享元对象(对象池获取,实现对象共享)
*/
public Style createStyle(String color){
Style style = styles.get(color);
if(style ==null){
style = new Style(color,defaultShape,defaultLength,defaultWeigth);
styles.put(color,style);
}
return style;
}
}
public class TestFlyweight {
public static void main(String[] args) {
StyleFactory styleFactory = new StyleFactory("圆形",2,2);
System.out.println("棋手1在2行2列下了一个白子。。");
Chess chess_2_2_w = new Chess(2,2,styleFactory.createStyle("white"));
System.out.println("棋手2在2行3列下了一个黑子。。");
Chess chess_2_3_b = new Chess(2,3,styleFactory.createStyle("black"));
System.out.println("棋手1在3行2列下了一个白子。。");
Chess chess_3_2_w = new Chess(3,2,styleFactory.createStyle("white"));
System.out.println("棋手2在3行3列下了一个黑子。。");
Chess chess_3_3_b = new Chess(3,3,styleFactory.createStyle("black"));
System.out.println(chess_2_2_w.getStyle() == chess_3_2_w.getStyle());
System.out.println(chess_2_3_b.getStyle() == chess_3_3_b.getStyle());
System.out.println(chess_2_2_w.getStyle() == chess_2_3_b.getStyle());
}
}
测试结果: