享元模式~

“享元”我们可以理解为共享元素,比如我们生活中的共享单车,共享充电宝,共享汽车,这样做的目的就是为了提高资源的复用,但对于共享的单车,充电宝等,它的拥有者和创建时间是不相同的,但是它核心的东西都是一致的,那么如果在我们的程序中有很多重复的对象,就会造成很大的内存开销

在享元模式中,它将元素分为两种状态一部分是内部状态,例如共享单车,这部分是可以完全被共享的,但是对于共享单车的另一部分资源,比如拥有者和创建时间,这部分信息是由客户端来决定的,谁此时使用,那么这部分的信息就是和谁有关的。

享元模式实现共享的核心是,我们不需要关心外部状态,将核心的资源包围起来共享出去,它内部信息都不会随着环境改变而改变,而外部状态,它会随着环境的改变而改变,这部分信息一定不是由我们自己来保存,共享对象一定不会保存这部分信息,这部分信息由客户端保存,客户端在用的时候,传入到享元对象内部,享元对象内部可以自己做一些处理,去使用或者展示他们,享元模式运用共享技术有效地支持大量细类度[细类度对象是指在某个类别下,具有不同属性或特征的对象,可以看作是对于一个类别的细分]的对象,享元模式最典型的应用就是池技术,比如字符串常量池,数据库连接池,线程池等等,他们都是实现了对共享元素的有效利用,避免去创建大量重复的对象,有效地利用资源。

享元对象的内部状态和环境是没有任何关系的,那么外部状态如何传入呢?方法即为我们在定义享元的时候可以定义一些方法,用于将外部状态传入,这样就实现了一个享元对象既有内部状态,也可以接受外部状态

享元模式~_第1张图片

实例:

1:创建抽象的享元对象

package com.wjr.xiangyaunModel.shared_power_bank;

abstract class PowerBankWeight {//抽象的享元对象
    protected int state=0;//0表示未使用,1表示使用
   abstract void getPowerBank(String username);
    abstract void backPowerBank();
}

2:创建具体的享元对象

package com.wjr.xiangyaunModel.shared_power_bank;

public class LvPowerBankWeight extends PowerBankWeight{
    protected String id;
    public LvPowerBankWeight(String id) {
        this.id=id;
    }

    @Override
    void getPowerBank(String userName) {
        state=1;//表示当前为使用状态
        System.out.println(userName+"正在使用"+id+"号充电宝");

    }

    @Override
    void backPowerBank() {
            state=0;//表示当前为未使用状态
    }
}

3:创建享元对象工厂

package com.wjr.xiangyaunModel.shared_power_bank;

import java.util.HashSet;

public class PowerBankFlyWeightFactory {
    private static PowerBankFlyWeightFactory powerBankFlyWeightFactory=new PowerBankFlyWeightFactory();
    HashSet<LvPowerBankWeight> pool=new HashSet<>();//享元对象池--数据结构不唯一,也可选择TreeSet,如何进行选择需要我们根据需求进行分析

    public static PowerBankFlyWeightFactory getPowerBankFlyWeightFactory(){
        return powerBankFlyWeightFactory;
    }

    public PowerBankFlyWeightFactory() {
        //表示享元对象的数量为3
        for(int i=0;i<3;i++){
            pool.add(new LvPowerBankWeight(i+"号"));
        }
    }
    public  LvPowerBankWeight getPowerBank(){
        for(LvPowerBankWeight lvPowerBankWeight:pool){
            if(lvPowerBankWeight.state==0){
                return lvPowerBankWeight;
            }
        }
        return null;
    }
}
package com.wjr.xiangyaunModel.shared_power_bank;

public class FlyWeightPattern {
    public static void main(String[] args) {
        LvPowerBankWeight lvPowerBankWeight1=PowerBankFlyWeightFactory.getPowerBankFlyWeightFactory().getPowerBank();
        lvPowerBankWeight1.getPowerBank("小学牲");
        lvPowerBankWeight1.backPowerBank();

        LvPowerBankWeight lvPowerBankWeight2=PowerBankFlyWeightFactory.getPowerBankFlyWeightFactory().getPowerBank();
        lvPowerBankWeight2.getPowerBank("中学牲");
//        lvPowerBankWeight2.backPowerBank();

        LvPowerBankWeight lvPowerBankWeight3=PowerBankFlyWeightFactory.getPowerBankFlyWeightFactory().getPowerBank();
        lvPowerBankWeight3.getPowerBank("大学牲");
//        lvPowerBankWeight3.backPowerBank();

        LvPowerBankWeight lvPowerBankWeight4=PowerBankFlyWeightFactory.getPowerBankFlyWeightFactory().getPowerBank();
        lvPowerBankWeight4.getPowerBank("打工人");
        lvPowerBankWeight4.backPowerBank();
    }
}

输出如下所示:

小学牲正在使用1号号充电宝
中学牲正在使用1号号充电宝
大学牲正在使用2号号充电宝
打工人正在使用0号号充电宝

享元模式通过池技术,可以确保内存中相同或相似的对象只保留一份,可以大大节约系统资源,提高系统的性能,享元模式的外部状态相对独立,不会影响内部状态,内外环境分离,使得享元对象可以在不同环境中被共享,因为它将状态区分出来,将外部状态由客户端指定,内部状态自己维护,这样使得它能够在不同环境中进行共享,它的缺点也很明显,因为我们要分离出内外状态,因此程序的逻辑性会比较复杂一点。外部状态都需要客户端传入,这也会影响它的运行时间

你可能感兴趣的:(设计模式,享元模式,开发语言,java,后端,设计模式)