享元模式(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 Listpool = 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个人租赁得到的充电宝实例是一致的。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)