享元模式

Posted 09120912zhang

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了享元模式相关的知识,希望对你有一定的参考价值。

来自书籍-------------设计模式之禅

享元模式:是池技术的重要实现,使用共享对象可有效支持大量的细粒度的对象。  定义两个要求  细粒度的对象和共享对象。 

  要求细粒度的对象就必然会存在大量且性质相似的对象,我们将对象的信息分为两个部分  内部状态 和外部状态

   内部状态 是对象可共享的信息,存储在享元对象内部并且不会随环境改变而改变.

   外部状态 是对象得以依赖的一个标记,是随环境而改变的,不可以共享的状态

 

下面以书中例子为依据

 技术分享图片

SignInfo 对象主要由4中location 和 30中subject组成 ,所以可以构建一个池来存储这120个对象,从而实现对象共享

 

SignInfo.java

package com.designModel.sharedModel;

/**
 * 报考信息
 */
public class SignInfo {

    private String location;

    private String subject;

    public String getLocation() {
        return location;
    }

    public void setLocation(String location) {
        this.location = location;
    }

    public String getSubject() {
        return subject;
    }

    public void setSubject(String subject) {
        this.subject = subject;
    }

}

 

 

SignInfo4Pool.java

package com.designModel.sharedModel;

public class SignInfo4Pool extends SignInfo {

    //定义一个对象池提取的key值
    private String key;


    public SignInfo4Pool(String key) {
        this.key = key;
    }


    public String getKey() {
        return key;
    }

    public void setKey(String key) {
        this.key = key;
    }


}

 

 

SignInfoFactory.java

package com.designModel.sharedModel;

import java.util.HashMap;

public class SignInfoFactory {

    //容器池  String类型 表示外部状态(最好以java基本类型为标志)
    private static HashMap<String, SignInfo> pool = new HashMap<>();


    public static SignInfo getSignInfo(String key) {

        SignInfo result = null;
        if (!pool.containsKey(key)) {
            result = new SignInfo4Pool(key);
            pool.put(key, result);
            System.out.println("建立对象,并放置到线程池中");

        }else{
            result = pool.get(key);
            System.out.println("从线程池中取出对象");
        }
        return result;
    }

}

 

 

Client.java调用代码

package com.designModel.sharedModel;

public class Client {

    public static void main(String... args) {

        for (int i=0;i<4;i++) {
            String subject = "科目" + i;
            for (int j=0;j<30;j++) {
                String key = subject + "考试地点" + j;
                SignInfoFactory.getSignInfo(key);
            }
        }

        SignInfoFactory.getSignInfo("科目1考试地点2");

    }
}

 

 

享元模式的通用类图

 

技术分享图片

 

 Flyweight---------------抽象享元角色

它简单地说是就是一个产品的抽象类,同时定义出对象的外部状态和内部状态的接口或实现。

 

ConcreteFlyweight---------------具体享元角色

具体的一个产品类,实现抽象角色定义的业务,该角色需要注意的是内部状态处理应该与环境无关。

 

unsharedConcreteFlyweight -----------------不可共享的享元角色

具体作用不太清楚??????

 

FlyweightFactory ---------享元工厂

职责就是构造一个池容器,同时提供从池中获取对象的方法。

 

 

个人总结  其实享元模式 就是共享对象,避免创建多个相同的对象,这类似与java中String 字符串    String str1="abc"  String str2="abc"   str1==str2  为true , 其实 str1和 str2都指向同一个字符串"abc",而"abc"放置在字符串常量池中,这就是共享模式的应用。

 

以上是关于享元模式的主要内容,如果未能解决你的问题,请参考以下文章

11-享元(Flyweight)模式Ruby实现

设计模式课程 设计模式精讲 13-1 享元模式coding

常用设计模式系列之——享元模式

23种设计模式之享元模式代码实例

享元模式

享元模式(Flyweight)