本篇介绍结构型模式中的享元模式。
享元模式
运用共享技术有效的支持大量细粒度的对象。
使用享元模式可以防止系统中产生过多同一个类的类似的对象,这里的类似对象指的是有些属性值是相同的,有些属性值是不同的。而相同的部分在享元模式中又被称为内部状态,不同的部分又被称为外部状态。内部状态是不会变的,外部状态通常会随着环境的改变而改变。
例如富士康如果每生产一部iphone就new一个iphone对象,给系统的压力山大,这个时候我们就可以使用享元模式。假如iphone11除了颜色其他都是相同的,那颜色就可以作为享元模式的外部状态,其他例如处理器就可以作为内部状态,即对于iphone11来说处理器是可以共享的,都是A13处理器。
类图
-
抽象享元角色:Iphone11类,定义了传入外部状态的方法;
-
具体享元角色:ColoredIphone11类,共享类;
-
享元工厂:WorkShop类,用来创建和管理享元对象,维护的池中有此对象则返回,无此对象则new一个,单例的。
具体实现
抽象享元角色:
abstract class Iphone11 {
protected String color;
Iphone11(String color) {
this.color = color;
}
abstract void showColor();
}
具体享元角色:
class ColoredIphone11 extends Iphone11 {
ColoredIphone11(String color) {
super(color);
}
@Override
void showColor() {
System.out.println("我买的是"+color+"的iphone11...");
}
}
享元工厂:
class WorkShop {
private Map<String,Iphone11> iphone11Map = new HashMap<>();
private WorkShop(){
System.out.println("富士康成立啦...");
}
public Iphone11 getIphone11(String color) {
Iphone11 iphone11 = null;
if (iphone11Map.containsKey(color)) {
iphone11 = iphone11Map.get(color);
} else {
iphone11 = new ColoredIphone11(color);
iphone11Map.put(color,iphone11);
}
return iphone11;
}
private static class Foxconn {
private static WorkShop workShop = new WorkShop();
}
public static WorkShop getWorkShop() {
return Foxconn.workShop;
}
}
测试程序及输出结果:
//测试程序
public static void main(String[] args) {
WorkShop workShop1 = WorkShop.getWorkShop();
WorkShop workShop2 = WorkShop.getWorkShop();
System.out.println("********单例模式********");
System.out.println("车间1 workShop1与车间2 workShop2是否是同一个车间呢:"+(workShop1==workShop2));
System.out.println("********享元模式********");
Iphone11 blackIphone11 = workShop1.getIphone11("黑色");
Iphone11 redIphone11 = workShop1.getIphone11("红色");
Iphone11 alsoBlackIphone11 = workShop1.getIphone11("黑色");
blackIphone11.showColor();
redIphone11.showColor();
alsoBlackIphone11.showColor();
System.out.println("黑色的iphone11和红色的iphone11是同一个对象么:"+(blackIphone11==redIphone11));
System.out.println("两个黑色的iphone11是同一个对象么:"+(blackIphone11==alsoBlackIphone11));
}
//输出结果
富士康成立啦...
********单例模式********
车间1 workShop1与车间2 workShop2是否是同一个车间呢:true
********享元模式********
我买的是黑色的iphone11...
我买的是红色的iphone11...
我买的是黑色的iphone11...
黑色的iphone11和红色的iphone11是同一个对象么:false
两个黑色的iphone11是同一个对象么:true
总结
内部状态对于同一享元是不变的,外部状态则决定了是否为同一享元对象,根据客户端传入的参数的改变而改变。享元模式与单例模式的差别在于单例模式中一个类的对象只有唯一一个,享元模式的对象会有多个,每个对象之间的差异在于外部状态。