享元模式:对于一些有共享功能的对象,减少他们的创建次数,提高重复利用对象的模式。
就是说,对于一些可以并且会多次利用的对象,我们创建一次然后把它放在一个地方,用的时候直接从这里拿,不需要反复创建对象,重复利用已有的对象。
举个例子,
假如现在有一家租车店,老板总不会有人来租车了才现买一辆车吧,他肯定是提前准备号一定数量的车,这一辆车就是一个对象,同一辆车会被反复借出。就简单模拟一下这个场景
// 先定义个抽象的车,为了规范一些行为和属性
public abstract class Car {
protected String brand;
public Car(String brand) {
this.brand = brand;
}
abstract void drive(String from);
}
两种类型的车
public class Tesla extends Car{
public Tesla(String brand) {
super(brand);
}
@Override
public void drive(String from) {
System.out.println(brand + " 被 " + from + " 租走了");
}
}
public class Jeep extends Car{
public Jeep(String brand) {
super(brand);
}
@Override
void drive(String from) {
System.out.println(brand + " 被 " + from + " 租走了");
}
}
准备两辆具体的车放在店里(carFactory)
// 工厂设置未单例
public class CarFactory {
public Map<String, Car> carMap = new HashMap<>();
// 准备好具体的车
private CarFactory() {
carMap.put("tesla", new Tesla("TESLA"));
carMap.put("jeep", new Tesla("JEEP"));
}
private static final CarFactory carFactory = new CarFactory();
public static CarFactory getInstance(){
return carFactory;
}
}
测试使用:
public class Client {
public static void main(String[] args) {
//通过carFactory获取车辆对象
CarFactory carFactory = CarFactory.getInstance();
// Car car01 = carFactory.carMap.get("tesla");
Car car01 = carFactory.carMap.get("jeep");
System.out.println(car01.brand);
// 这个对象可以反复使用
car01.drive("老赵");
car01.drive("小张");
car01.drive("Tom");
// 再次获取同样的对象,其实是同一个对象
Car car02 = carFactory.carMap.get("jeep");
System.out.println(car01 == car02);
}
}
这里的carFactory就相当于这个租车店,它提前会准备一些车,随时等客人来租。
小结一下:这个享元模式,我感觉核心其实就是这种缓存池的思想。就是把一些会反复用到的数据对象放入池中,用的时候直接从池中取,避免每次都新建,可以理解为单例对象的集合。比如spring的bean集合,还有线程池,都有类似的原理。包括我们在开发中,如果需要在循环中反复获取一些公共信息,也可以提前把这些信息放入到一个map中,然后循环中直接从map中获取,我觉得都是这种思想的应用。
但是使用这种模式也需要注意,使用前需要对数据对象进行评估,必须是真的会反复使用的数据才有必要,要不然就是浪费内存资源了。