您的位置:首页 > 编程语言 > Java开发

享元模式 Java

2016-06-06 00:35 344 查看
一个类A有诸多的成员变量,创建一个A对象需要在堆中为该对象分配空间。假设,需要创建十万个A对象,那么A的成员变量中,有没有一成不变的某些数据的组合呢?如果能够将这些数据组合加以类型化——称为轻量级或鸿毛/羽毛/Flyweight对象,那么十万个A对象可以共享Flyweight对象,从而有效地降低内存开销。

Flyweight设计模式,直译为轻量级、鸿毛模式,意译为共享单元模式简称享元模式。

属性对象

假设Car对象有如下属性:

     String owner;//车主,例程中略

     String name;//车型名称

     Color color;//车的颜色

     int X,Y; //GPS定位坐标

     int length,width,height;//车体的几何尺寸

如果创建十几个Car对象,我们不需要过多考虑。如果创建武汉市所有轿车的对象,那么Car对象的成员变量就需要仔细分析。①GPS定位坐标X和Y,是每时每刻都在变化的,不考虑共享;车主owner,大多数Car的owner是私人,除非owner是公交或的士公司才考虑它;车的颜色变化也比较多;②车型名称和车体的几何尺寸,这种数据组合是固定的,虽然奥迪A6和奥迪A4分别有不同取值,但数据组合是固定的。于是,可以设计一个鸿毛flyweight类型,用于保存数据组合。

package property.flyweight;
public interface ICarUnit{
public String getName();
public double getHeight();
public double getWidth();
public double getLength();
public void printMess(String mess);
}//具体子类暂缓
ICarUnit对象将被Car对象共享。例如,创建的表示奥迪A6、奥迪A4、东风标致2008、东风标致4008的羽毛对象都将被共享。

如何管理共享的对象?

通常

每种享元对象仅创建一个,而且可以通过一个HashMap管理这些对象。
 外界不得创建享元对象,而是使用HashMap所管理的共享对象。

因而,管理共享对象的工作,抽象并封装成一个类。GoF中,称其为享元工厂(FlyweightFactory),而yqj2065通常称其为享元池(FlyweightPool)。

享元工厂这一称呼,从内部说明了该类包含一个静态工厂,并按照HashMap的key获得羽毛对象,如方法

public static synchronized  ICarUnit getFlyweight(String key)

享元池这一称呼,从外界用户的感受,说明该类的作用就是维护一个对象池。真正持有数据的享元CarUnit(即ICarUnit的实现类),因为和享元池/享元工厂关系密切,通常设计为享元池的内部类。
package property.flyweight;
import java.util.HashMap;
public class FlyweightPool{
private static  HashMap<String,ICarUnit>  hashMap;
static{hashMap=new HashMap<String,ICarUnit>();}
private FlyweightPool(){    }
public static synchronized ICarUnit getUnit(String name,double length,double width,double height){
String key = name;
if(hashMap.containsKey(key))
return hashMap.get(key);
else{
ICarUnit flyweight = new CarUnit(name,width,height,length);
hashMap.put(key,flyweight);
return flyweight;
}
}

static final class CarUnit implements ICarUnit{
private String name;
private double width;
private double height;
private double length;
private CarUnit(String name,double width,double height,double length){
this.name =name;
this.width=width;
this.height=height;
this.length=length;
}

public String getName(){         return name;        }
public double getHeight(){       return height;        }
public double getWidth(){        return width;        }
public double getLength(){       return length;        }

public void printMess(String mess){
System.out.print(mess);        //输出外部数据mess
System.out.print(" 宽度:"+width);  //输出内部数据width
System.out.print(" 高度:"+height);
System.out.println("长度:"+length);
}
}
}

JVM中的享元

Integer 、 Byte、Short、Long和Character使用了享元模式。Character (from 0 to 127) 、其他(from -128 to 127)。而最典型的则是String。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: