设计模式专栏——享元模式(FlyWeight)

设计模式专栏——享元模式(FlyWeight),第1张

设计模式专栏——享元模式(FlyWeight) 概述

享元模式(Flyweight Pattern)主要用于减少创建对象的数量,以减少内存占用和提高性能。这种类型的设计模式属于结构型设计模式,它提供了减少对象数量从而改善应用所需的对象结构的方式。它的核心结构有四个角色:抽象享元角色(AbstractFlyWeight)、具体享元角色(ConcreteFlyWeight)、享元工厂(FlyWeightFactory)、客户端(Client)。

(1) 抽象享元角色:为具体享元角色规定了必须实现的方法,在Java中可以是抽象类,可以是接口。

(2) 具体享元角色:实现抽象角色定义的方法。

(3) 享元工厂角色:生成FlyWeight角色的工厂,在工厂中生成的FlyWeight角色可以实现共享实例。 

(4) 客户端角色:Client角色使用FlyWeightFactory来生成FlyWeight角色。

池化技术都是这种模式的实现,数据库连接池、线程池、字符串常量池等等。生活中也有很多这种例子,比如共享单车、共享充电宝、共享雨伞等等。接下来我们以共享充电宝为例展开讨论。

类图

示例

抽象享元角色

public abstract class SharePortableBattery {

    //0是未使用,1是使用中
    protected int state = 0;
    //租赁时长,单位分钟
    protected long rentTime = 0;

    
    abstract void rent(String userName);

    
    abstract void back(long rentTime);

    public void setState(int state){
        this.state = state;
    }

    public int getState() {
        return state;
    }

    public long getRentTime() {
        return rentTime;
    }

}

具体享元角色

public class MonsterSharePortableBattery extends SharePortableBattery{
    //充电宝id
    private int batteryId;
    //使用时长
    private long rentTime;

    public MonsterSharePortableBattery(int batteryId) {
        this.batteryId = batteryId;
    }

    public int getBatteryId(){
        return batteryId;
    }

    public void setRentTime(long rentTime){
        this.rentTime = rentTime;
    }

    public long getRentTime(){
        return rentTime;
    }

    @Override
    void rent(String userName) {
        SharePortableBatteryFactory.getInstance().setState(batteryId, 1);
        System.out.println(userName + "租赁" + batteryId + "号 充电宝!");
    }

    @Override
    void back(long rentTime) {
        SharePortableBatteryFactory.getInstance().setRentTime(batteryId, rentTime);
        System.out.println(batteryId + "号 充电宝归还!");
    }

}

享元工厂

public class SharePortableBatteryFactory {
    private static SharePortableBatteryFactory instance = new SharePortableBatteryFactory();
    private static List pool = new ArrayList<>();

    public static SharePortableBatteryFactory getInstance() {
        return instance;
    }

    static{
        for (int i = 0; i < 4; i++) {
            pool.add(new MonsterSharePortableBattery(i));
        }
    }

    
    public MonsterSharePortableBattery getBattery() {
       List sortedPool =  pool.stream().filter(v -> v.getState() == 0).sorted(Comparator.
               comparing(MonsterSharePortableBattery::getRentTime)).collect(Collectors.toList());
        if(!CollectionUtils.isEmpty(sortedPool)){
            return sortedPool.get(0);
        }
        return null;
    }

    
    public void setRentTime(int batteryId, long rentTime) {
        for (MonsterSharePortableBattery battery : pool) {
            if (battery.getBatteryId() == batteryId){
                battery.setRentTime(battery.getRentTime() + rentTime);
                battery.setState(0);
                break;
            }
        }
    }

    
    public void setState(int batteryId, int state) {
        for (MonsterSharePortableBattery battery : pool) {
            if (battery.getBatteryId() == batteryId){
                battery.setState(state);
                break;
            }
        }
    }
}

客户端

    public static void main(String[] args) {
        SharePortableBattery battery1 = SharePortableBatteryFactory.getInstance().getBattery();
        battery1.rent("关羽");
        battery1.back(20);

        SharePortableBattery battery2 = SharePortableBatteryFactory.getInstance().getBattery();
        battery2.rent("张飞");
        battery2.back(10);

        SharePortableBattery battery3 = SharePortableBatteryFactory.getInstance().getBattery();
        battery3.rent("赵云");
        battery3.back(15);

        SharePortableBattery battery4 = SharePortableBatteryFactory.getInstance().getBattery();
        battery4.rent("马超");
        battery4.back(35);

        SharePortableBattery battery5 = SharePortableBatteryFactory.getInstance().getBattery();
        battery5.rent("黄忠");
        battery5.back(40);

        System.out.println(battery5 == battery2);
    }

我们在享元工厂里初始化了4个充电宝享元实例,所以第5个人租赁和第2个人租赁得到的充电宝实例是一致的。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5696433.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-17
下一篇 2022-12-17

发表评论

登录后才能评论

评论列表(0条)

保存