享元模式定义
重用现有的类,通过缓存的构造理念,将状态相同,复用性多且状态变化小的对象存储于缓存中(享元模式在存储于hashmap中,且存储map中的对象为类的"模板",并不是全部类的实例),适用于有着大量的对象实例时使用。
享元模式实现
public interface FlyweightInterface {
void same();
}
抽象享元类 需要重用类中使用到的的方法。
public class SameMode implements FaceInterface{
private String name;
private int price;
private int age;
public SameMode(String name) {
this.name = name;
}
public void setName(String name) {
this.name = name;
}
public void setPrice(int price) {
this.price = price;
}
public void setAge(int age) {
this.age = age;
}
@Override
public void food() {
System.out.println("SameMode{" +
"name='" + name + '\'' +
", price=" + price +
", age=" + age +
'}');
}
}
共享享元类,即需要重用的类。实现抽象享元类实现其方法。
public class ModeFactory {
public static final HashMap<String, FaceInterface> maps = new HashMap<>();
public static SameMode getSame(String name) {
SameMode mode = (SameMode)maps.get(name);
if (mode == null) {
mode = new SameMode(name);
maps.put(name, mode);
System.out.println("create mode food" + name);
}
return mode;
}
}
享元类存储于HashMap以唯一标识为Key存储类的"模板",如果存在即获取,失败则创建。相信看到这里,就能联想到后面的线程安全问题了。
public class FlyweightTest {
private static final String[] strings = new String[] {"chicken", "beef", "pig"};
private static Random random = new Random();
public static void main(String[] args) {
for (int i = 0; i <20 ; i++) {
SameMode s = ModeFactory.getSame(strings[getRandom()]);
s.setAge(getandom1());
s.setPrice(getandom1());
s.food();
}
}
private static int getRandom() {
return random.nextInt(3);
}
private static int getandom1() {
return random.nextInt(100);
}
}
测试类 创建多个根据享元模式创建的对象
// 测试结果
create mode foodbeef
SameMode{name='beef', price=89, age=77}
SameMode{name='beef', price=53, age=48}
create mode foodchicken
SameMode{name='chicken', price=45, age=5}
SameMode{name='beef', price=38, age=80}
SameMode{name='beef', price=80, age=19}
create mode foodpig
SameMode{name='pig', price=4, age=98}
SameMode{name='chicken', price=43, age=69}
SameMode{name='beef', price=7, age=56}
SameMode{name='beef', price=49, age=11}
SameMode{name='beef', price=12, age=35}
SameMode{name='beef', price=29, age=7}
SameMode{name='chicken', price=72, age=34}
SameMode{name='chicken', price=3, age=26}
SameMode{name='beef', price=8, age=95}
SameMode{name='pig', price=64, age=77}
SameMode{name='chicken', price=53, age=51}
SameMode{name='pig', price=47, age=18}
SameMode{name='pig', price=82, age=71}
SameMode{name='pig', price=43, age=17}
SameMode{name='chicken', price=13, age=38}
Process finished with exit code 0
小结
- 优点:如果有相同的业务请求,直接返回在内存中已有的对象,避免重新创建,减少了类的重复创建减少了内存的使用
- 缺点:实例存于线程共享的堆中,因此有着线程安全问题,在多线程的环境下需要对应的同步块或者独占锁实现。
详细源码下载地址: github.com/Liyinzuo/De…
以上便是享元模式介绍,如果那里错误或者不足地方欢迎指正。