一个类中的成员变量表明这个类所创建的对象具有的属性,而我们可能会使用程序的中某一个类创建多个对象,你们这些对象之间可能会存在一部分属性值是完全相同的。现在我们创建一个Car类,然后用这个类创建carA和carB两辆同型号的轿车他们的长宽高相同,但颜色和功率不同
我们创建的carA和carB两个实例对象,这两个对象长宽高完全相同,但他们占有不同的内存空间,所以我们用Car类实例化的对象越多,浪费的内存空间也就越多
因为他们有着不同的内存空间,那么他们就可能会修改自己的属性值,那么我们就不能保证相同型号的汽车的长宽高是一致的
我们能否考虑让Car类创建的所有实例对象共享相同的height,width和length属性呢?答案是可以的,我们可以将Car类在红的height,width和length封装到一个新的类中
这样Car类创建的若干个实例对象都只要给color和power分配不同的内存空间,让这些对象可以共享同一个carData对象
享元(Flyweight)模式:运用共享技术来有效地支持大量细粒度对象的复用。
享元模式的关键是使用一个享元对象为其他对象提供共享的状态,从而保证使用享元的对象不能更改享元的数据
享元:享元对象其实就是一个共享对象,"引入"中所提到的CarData类的实例就是一个享元对象
以围棋为例,围棋分为黑子和白子,黑子和白字之间有着诸多相似的属性,除去颜色外,每颗棋子不同的是在棋盘上的位置。因此,我们可以分析出围棋对象的内部状态和外部状态
内部状态:比如说,棋子的颜色,大小,质量(近似相等),制造商等等
外部状态:棋子在棋盘中的位置
//抽象享元:这是一个抽象类
public abstract class Flyweight {
// 定义了一个抽象方法,用来输出棋子的颜色和坐标
public abstract void show(Location loc);
}
//具体享元类:白棋
public class WhiteChessman extends Flyweight {
public String color = "white";
public String getColor() {
return color;
}
// 重写父类的抽象方法,将外部状态Location对象传给内部对象,一起输出
public void show(Location loc) {
// TODO Auto-generated method stub
System.out.println(getColor() + ":" + loc.getLoc());
}
}
//具体享元类:黑棋
public class BlackChessman extends Flyweight {
public String color = "black";
public String getColor() {
return color;
}
// 重写父类的抽象方法,将外部状态Location对象传给内部对象,一起输出
public void show(Location loc) {
// TODO Auto-generated method stub
System.out.println(getColor() + ":" + loc.getLoc());
}
}
//非共享的具体享元类:设定棋子的坐标
public class Location {
public int x;
public int y;
// 设定坐标
public Location(int x, int y) {
setX(x);
setY(y);
}
// 获取棋子的坐标
public String getLoc() {
return "x:" + getX() + ",y:" + getY();
}
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;
}
}
import java.util.HashMap;
//享元工厂了
public class FlyweightFactory {
// HashMap用来存放不同的具体享元实例,每个具体享元实例只有一个,可以和单例模式配合使用
public HashMap<String, Flyweight> flyweights = new HashMap<>();
public FlyweightFactory() {
// 直接向HashMap中添加两个具体享元实例
flyweights.put("white", new WhiteChessman());
flyweights.put("black", new BlackChessman());
}
// 根据传入的color,在HashMap中匹配对应颜色的棋子
public Flyweight getFlyweight(String color) {
return flyweights.get(color);
}
}
public class Client {
public static void main(String[] args) {
//生成一个享元工厂
FlyweightFactory factory = new FlyweightFactory();
//获取白棋
Flyweight white1 = factory.getFlyweight("white");
Flyweight white2 = factory.getFlyweight("white");
white1.show(new Location(1,2)); //给白棋传一个坐标
white2.show(new Location(2,4)); //给白棋传一个坐标
//每个白棋如果除去坐标以后,他们是完全相同的
System.out.println(white1.hashCode() == white2.hashCode());
System.out.println("--------------");
//获取黑棋
Flyweight black1 = factory.getFlyweight("black");
Flyweight black2 = factory.getFlyweight("black");
black1.show(new Location(1,2));
black2.show(new Location(3,5));
//每个黑棋如果除去坐标以后,他们是完全相同的
System.out.println(black1.hashCode() == black2.hashCode());
System.out.println("--------------");
//黑棋和白棋是不同的
System.out.println(white1.hashCode() == black1.hashCode());
}
}
//执行结果
white:x:1,y:2
white:x:2,y:4
true
--------------
black:x:1,y:2
black:x:3,y:5
true
--------------
false
与其他模式的关系