ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

DesignPattern-享元模式

2019-03-03 11:49:51  阅读:272  来源: 互联网

标签:享元 String extrinsic 模式 DesignPattern Flyweight operate public


享元模式:String常量池,数据库连接池,缓冲池等等都是享元模式的应用。

每次创建字符创对象时候,都需要创建一个新的字符串对象的话,内存开销很大,所以如果第一次创建了字符串对象hunter,下次在创建相同的字符串hunter时,只是把它的引用再次指向hunter,这样就实现了hunter字符串内内存中的共享。

角色:
Flyweight:抽象享元类,所有具体享元类的超类or接口,
ConcreteFlyweight:具体享元类,指定内部状态,为内部状态增加存储空间
UnsharedConcreteFlywight: 非共享具体享元类。支出那些不需要共享的Flyweight子类
FlyweightFactory:享元工厂类,用来创建并管理Flyweight对象,它主要用来确保合理地共享Flyweight,当用户请求一个Flyweight时,工厂会提供一个已经创建的对象or新建一个(如果不存在)

代码实现:
Flyweight

public abstract class Flyweight {

    //内部状态
    public String intrinsic;
    //外部状态
    protected final String extrinsic;
    
    //要求享元角色必须接受外部状态
    public Flyweight(String extrinsic) {
        this.extrinsic = extrinsic;
    }
    
    //定义业务操作
    public abstract void operate(int extrinsic);

    public String getIntrinsic() {
        return intrinsic;
    }

    public void setIntrinsic(String intrinsic) {
        this.intrinsic = intrinsic;
    }

}

ConcreteFlywight

public class ConcreteFlyweight extends Flyweight {

    //接受外部状态
    public ConcreteFlyweight(String extrinsic) {
        super(extrinsic);
    }

    //根据外部状态进行逻辑处理
    @Override
    public void operate(int extrinsic) {
        System.out.println("具体Flyweight:" + extrinsic);
    }

}

UnsharedConcreteFlyweight

public class UnsharedConcreteFlyweight extends Flyweight {

    public UnsharedConcreteFlyweight(String extrinsic) {
        super(extrinsic);
    }

    @Override
    public void operate(int extrinsic) {
        System.out.println("不共享的具体Flyweight:" + extrinsic);
    }

}

FlyweightFactory

public class FlyweightFactory {

    //定义一个池容器
    private static HashMap<String, Flyweight> pool = new HashMap<>();
    
    //享元工厂
    public static Flyweight getFlyweight(String extrinsic) {
        Flyweight flyweight = null;
        
        if(pool.containsKey(extrinsic)) {    //池中有该对象
            flyweight = pool.get(extrinsic);
            System.out.print("已有 " + extrinsic + " 直接从池中取---->");
        } else {
            //根据外部状态创建享元对象
            flyweight = new ConcreteFlyweight(extrinsic);
            //放入池中
            pool.put(extrinsic, flyweight);
            System.out.print("创建 " + extrinsic + " 并从池中取出---->");
        }
        
        return flyweight;
    }
}

测试程序:

public class Client {

    public static void main(String[] args) {
        int extrinsic = 22;
        
        Flyweight flyweightX = FlyweightFactory.getFlyweight("X");
        flyweightX.operate(++ extrinsic);
        
        Flyweight flyweightY = FlyweightFactory.getFlyweight("Y");
        flyweightY.operate(++ extrinsic);
        
        Flyweight flyweightZ = FlyweightFactory.getFlyweight("Z");
        flyweightZ.operate(++ extrinsic);
        
        Flyweight flyweightReX = FlyweightFactory.getFlyweight("X");
        flyweightReX.operate(++ extrinsic);
        
        Flyweight unsharedFlyweight = new UnsharedConcreteFlyweight("X");
        unsharedFlyweight.operate(++ extrinsic);
    }
    
}

第一次创建X、Y、Z时,都是先创建再从池中取出,而第二次创建X时,因为池中已经存在了,所以直接从池中取出

应用场景:
系统中存在大量相似对象
需要缓冲池的场景 比如:String常量池,数据库连接池

方法:
用唯一标识码判断,如果在内存中,则返回这个唯一标识码所标识的对象,用HashMap/HashTable存储

优点:
大大减少了对象的创建,降低了程序内存的占用,提高效率
缺点:
提高了系统的复杂度。需要分离出内部状态和外部状态,而外部状态具有固化性。不应该随着内部状态的改变而改变。

标签:享元,String,extrinsic,模式,DesignPattern,Flyweight,operate,public
来源: https://blog.csdn.net/u010122604/article/details/88086286

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有