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());
    }
}

【运行结果】

原文地址:https://www.cnblogs.com/HigginCui/p/6229957.html