1.描述
运用共享技术有效的支持大量细粒度的对象。
2.模式的使用
·享元接口(Flyweight):是一个接口,该接口定义了享元对外公开其内部数据的方法以及享元接受外部数据的方法。
·具体享元(Concrete Flyweight):实现享元接口的类的实例。享元类的构造方法必须是private的,不允许用户用户程序直接创建享元对象,创建和管理享元对象由享元工厂负责。这是因为具体享元类的成员变量为享元对象的内部状态,享元对象的内部状态必须与所处的环境无关,即要保证使用享元对象的应用程序无法更改享元对象的内部状态,这样才能使享元对象在系统中被共享。
·享元工厂(Flyweight Factory):享元工厂是一个类,该类的实例负责创建和管理享元对象。
3.使用情景
·一个应用程序用到大量对象,这些对象之间部分属性本质上是相同的。
·对象的多数状态都可变为外部状态,就可以考虑将这样的对象作为系统中的享元来使用。
4.优点
·可节省内存开销。
·享元模式中的享元可以使用方法中的参数接受外部状态中的数据,但外部状态数据不会干扰到享元中的内部数据,这就使享元可以在不同环境中被共享。
5.UML图
6案例
生产奥迪车型汽车,奥迪A6和奥迪A8,奥迪车型都具有相同的属性:长宽高;名字、颜色、功率可以不同。
1 import java.util.HashMap; 2 3 public class 享元模式 { 4 5 public static void main(String[] args) { 6 FlyweightFactory factory = FlyweightFactory.getFactory(); 7 double width = 1.82, height = 1.47, length = 5.12; 8 Flyweight flyweight = factory.getFlyweight(width, height, length); 9 Car aodiA6 = new Car(flyweight, "奥迪A6", "黑色", 128); 10 Car aodiA8 = new Car(flyweight, "奥迪A8", "灰色", 160); 11 aodiA6.print(); 12 aodiA8.print(); 13 width = 1.77; 14 height = 1.45; 15 length = 4.63; 16 flyweight = factory.getFlyweight(width, height, length); 17 aodiA6 = new Car(flyweight, "新版奥迪A6", "黑色的", 128); 18 aodiA8 = new Car(flyweight, "新版奥迪A8", "灰色的", 160); 19 aodiA6.print(); 20 aodiA8.print(); 21 } 22 23 } 24 25 /* 26 * 享元接口 27 */ 28 interface Flyweight{ 29 public double getHeight(); //返回内部数据 30 public double getWeight(); 31 public double getLength(); 32 public void printMess(String mess); //使用参数获取外部数据 33 } 34 35 /* 36 * 享元工厂与具体享元 37 */ 38 class FlyweightFactory{ 39 private HashMap<String,Flyweight> map; 40 static FlyweightFactory factory = new FlyweightFactory(); 41 42 private FlyweightFactory(){ 43 map = new HashMap<String,Flyweight>(); 44 } 45 46 public static FlyweightFactory getFactory(){ 47 return factory; 48 } 49 50 public synchronized Flyweight getFlyweight(double width, double height, double length){ 51 String key = "" + width + "#" + height + "#" + length; 52 if(map.containsKey(key)) 53 return map.get(key); 54 else{ 55 Flyweight ft = new ConcreteFlyweight(width, height, length); 56 map.put(key, ft); 57 return ft; 58 } 59 } 60 61 class ConcreteFlyweight implements Flyweight{//内部类 62 private double width, height, length; 63 64 private ConcreteFlyweight(double width, double height, double length){ 65 this.height = height; 66 this.width = width; 67 this.length = length; 68 } 69 70 public double getHeight() { 71 return height; 72 } 73 74 public double getWeight() { 75 return width; 76 } 77 78 public double getLength() { 79 return length; 80 } 81 82 public void printMess(String mess) { 83 System.out.println(mess); //输出外部数据 84 System.out.println("宽度" + width); //输出内部数据 85 System.out.println("高度" + height); 86 System.out.println("长度" + length); 87 } 88 89 } 90 } 91 92 /* 93 * 案例类 94 */ 95 class Car{ 96 Flyweight flyweight;//存放享元对象的引用 97 String name, color; 98 int power; 99 100 Car(Flyweight flyweight, String name, String color, int power){ 101 this.flyweight = flyweight; 102 this.name = name; 103 this.color = color; 104 this.power = power; 105 } 106 107 public void print(){ 108 System.out.print("名称:" + name + " "); 109 System.out.print("颜色:" + color + " "); 110 System.out.print("功率:" + power + " "); 111 System.out.print("宽度:" + flyweight.getWeight() + " "); 112 System.out.print("高度:" + flyweight.getHeight() + " "); 113 System.out.println("长度:" + flyweight.getLength() + " "); 114 115 } 116 }