DesignPattern-享元模式

版权声明:你天加练的全战攻城狮梦 https://blog.csdn.net/u010122604/article/details/88086286

享元模式: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存储

扫描二维码关注公众号,回复: 5399304 查看本文章

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

猜你喜欢

转载自blog.csdn.net/u010122604/article/details/88086286
今日推荐