首页 > 代码库 > 16_享元模式

16_享元模式

【享元模式】

享元模式是池技术的重要实现方式。

享元模式使用共享对象有效地支持大量细粒度的对象。

享元模式两个要求:细粒度对象和共享对象。在平时写java程序过程中,分配太多的对象到应用程序中将有损程序的心梗,同事还容易造成内存溢出,避免的方式之一就是采用享元模式的共享技术。

要求细粒度对象,那么不可避免的使得对象数量多,且性质相近,我们将这些对象信息分为两部分:内部状态(intrinsic)和 外部状态(exetrinsic)。

* 内部状态

内部状态是对象可共享出来的信息,存储在享元对象内部并且不会随环境改变而改变。它可以作为一个对象的动态附加信息,不必直接存储在摸个具体的对象中,属于共享的部分。

* 外部状态

外部状态时对象得以依赖的一个标记,是随着环境改变而改变的、不可共享的状态。它是一批对象的统一标识,是唯一的一个索引值,相当于Map的键值key。

 

[ 目的 ]

享元模式的目的在于使用共享技术,使得一些细粒度的对象可以共享,我们的设计应该多使用细粒度的对象,这样便于重用或重构。

 

【分类】

[ 单纯享元模式 ]

在单纯享元模式中,所有享元对象都是可以共享的。

由3部分组成:

* Flyweight 抽象享元角色

简单的说就是一个产品的抽象类或接口,以规定出所有具体享元角色需要实现的方法。

* ConcreteFlyweight 具体享元角色

具体的一个产品类,实现抽象享元角色定义的业务。

* FlyweightFactory 享元工厂

职责非常简单,即构造一个池容器,同时提供从池中获得对象的方法。当一个客户端调用一个享元对象的时候,享元工厂角色应该先从对象池中获取,有则直接;若对象池中没有,则新实例化一个,并在对象池中放入该新实例化的对象。

[ 复合享元模式 ]

复合享元模式是将一些单纯享元模式加以复合,形成复合享元对象。这样的复合享元对象本身无法共享,但是他们能分解成单纯享元对象,后者可以分享。

* Flyweight 抽象享元角色

简单的说就是一个产品的抽象类或接口,以规定出所有具体享元角色需要实现的方法。

* ConcreteFlyweight 具体享元角色

具体的一个产品类,实现抽象享元角色定义的业务。

* ConcreteCompositeFlyweight 复合享元角色(不可共享的享元对象unsharedConcreteFlyweight)

不存在外部状态或安全要求(如线程安全)不能够使用共享技术的对象,该对象一般不会出现在享元工厂中。也称为不可共享的享元对象。

* FlyweightFactory 享元工厂

职责非常简单,即构造一个池容器,同时提供从池中获得对象的方法。当一个客户端调用一个享元对象的时候,享元工厂角色应该先从对象池中获取,有则直接;若对象池中没有,则新实例化一个,并在对象池中放入该新实例化的对象。

 

【单纯享元模式 例子】

package com.Higgin.Flyweight;import java.util.HashMap;import java.util.Map;/** * 抽象享元角色  */interface Flyweight{    public void opetation();}/** * 具体享元角色 */class ConcreteFlyweight implements Flyweight{    private String state=null;        public ConcreteFlyweight(String state) {        this.state=state;    }        @Override    public void opetation() {        System.out.println("do some operation!");    }}/** * 享元对象的工厂类 */class FlyweightFactory{    //HashMap类型的对象池    private static Map<String,Flyweight> map=new HashMap<>();    /**     * 得到一个Flyweight     * 1.对象池中已有的,直接获取     * 2.对象池中没有的,实例化一个,然后放入对象池中     */    public static Flyweight getFlyweight(String state){        Flyweight flyweight=map.get(state);   //对象池中若有直接获取        if(flyweight==null){   //为null,即对象池中没有            System.out.println(state+" 不存在,需要实例化一个放入池中...");   //提示作用            flyweight=new ConcreteFlyweight(state);              map.put(state, flyweight);        }else{    //仅作为提示作用            System.out.println(state+" 已存在,无需实例化,直接取出...");     //提示作用        }        return flyweight;    }    //得到对象池中的对象数量    public static int getObjectNum(){          return map.size();    }}/** * 测试  单纯享元模式  */public class TestFlyweight {    public static void main(String[] args) {        Flyweight f1=FlyweightFactory.getFlyweight("小明");        Flyweight f2=FlyweightFactory.getFlyweight("小明");        Flyweight f3=FlyweightFactory.getFlyweight("小梦");        Flyweight f4=FlyweightFactory.getFlyweight("小杰");        Flyweight f5=FlyweightFactory.getFlyweight("小新");        Flyweight f6=FlyweightFactory.getFlyweight("小琴");        Flyweight f7=FlyweightFactory.getFlyweight("小琴");        System.out.println(f1==f2);        System.out.println(f5==f6);        System.out.println(f6==f7);        System.out.println("创建的对象数量:"+FlyweightFactory.getObjectNum());    }}

【运行结果】

技术分享

 

16_享元模式