享元模式 Java
2016-06-06 00:35
344 查看
一个类A有诸多的成员变量,创建一个A对象需要在堆中为该对象分配空间。假设,需要创建十万个A对象,那么A的成员变量中,有没有一成不变的某些数据的组合呢?如果能够将这些数据组合加以类型化——称为轻量级或鸿毛/羽毛/Flyweight对象,那么十万个A对象可以共享Flyweight对象,从而有效地降低内存开销。
Flyweight设计模式,直译为轻量级、鸿毛模式,意译为共享单元模式简称享元模式。
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类型,用于保存数据组合。
每种享元对象仅创建一个,而且可以通过一个HashMap管理这些对象。
外界不得创建享元对象,而是使用HashMap所管理的共享对象。
因而,管理共享对象的工作,抽象并封装成一个类。GoF中,称其为享元工厂(FlyweightFactory),而yqj2065通常称其为享元池(FlyweightPool)。
享元工厂这一称呼,从内部说明了该类包含一个静态工厂,并按照HashMap的key获得羽毛对象,如方法
public static synchronized ICarUnit getFlyweight(String key)
享元池这一称呼,从外界用户的感受,说明该类的作用就是维护一个对象池。真正持有数据的享元CarUnit(即ICarUnit的实现类),因为和享元池/享元工厂关系密切,通常设计为享元池的内部类。
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。相关文章推荐
- SPringMVC各层浅析
- java中Scanner类nextLine()和next()的区别和使用方法
- javaBean中 字符串 转 date 类型转换
- Java 设计模式——外观模式
- Java 设计模式——外观模式
- JavaSE_Java中的流重定向_重新定位到控制台
- spring-springmvc-shiro整合(转载)
- Java Web应用安全
- 异步Servlet
- Java Jest for Elasticsearch
- Spring4 MVC 整合Hibernate5 附源码下载
- Java之LinkedList源码解读(JDK 1.8)
- JAVA 内存泄露详解(原因、例子及解决)
- Java 并发
- 手把手教你从最基本的Java工程搭建SpringMVC+SpringDataJPA+Hibernate(含源码下载)
- java枚举分析
- JPA规范介绍及实例(Java数据持久化解决方案)
- Spring ORM+Hibernate?Out!换 Spring Data JPA 吧!
- 基于JDK 1.8 的 Java 容器UML图
- java中的正则表达式