解释器模式第一遍没有读懂,看到后面说实际项目中很少用到,因为它会引起效率、性能以及维护等问题,会直接用已有的成熟的工具。
又看了一遍有点明白了,有点类似写算法题遇到的情况,又有点编译原理里面的味道。不过既然用不到,像我这种三流的程序员也就不想深究了。
想想技术书永远别买纸书,技术更新太快,有些书买来很快就过期了,没用了,卖二手都卖不出去,再看也没太大价值,只能当废纸,成本太高。这《设计模式之禅》虽然没有技术过期的问题,但买了纸书,现在还是在看电子版的,在公司也不适合看纸书,而且属于看完记录完也不想再看的书。
以后凡是不需要阅读多遍的书,都不要花钱去买纸书。
享元模式
池中共享对象,减少对象创建,减小 OOM 机率。
比如 Android 从 xml 构建 View 时的构造器。Map 保存对象,有就拿出来用,没有再创建存到 Map 中去。
将对象的信息分成内部状态和外部状态两类,内部状态可以没有。外部状态就是需要调用者传进来的参数,来控制生成一个什么样的对象。通过这个状态判断池子里是否有可以直接复用的。
代码语言:javascript复制// 抽象的享元类
public abstract class Flyweight {
//内部状态
private String intrinsic;
//外部状态,final 不许子类修改
protected final String Extrinsic;
//要求享元角色必须接受外部状态。
public Flyweight(String _Extrinsic){
this.Extrinsic = _Extrinsic;
}
//定义业务操作
public abstract void operate();
//内部状态的getter/setter
}
// 具体的享元类
public class ConcreteFlyweight extends Flyweight{
//接受外部状态
public ConcreteFlyweight2(String _Extrinsic){
super(_Extrinsic);
}
//根据外部状态进行逻辑处理
public void operate(){
//业务逻辑
}
}
// 享元工厂
public class FlyweightFactory {
//定义一个池容器
private static HashMap<String,Flyweight> pool= new HashMap<String,Flyweight
//享元工厂,参数传入外部状态
public static Flyweight getFlyweight(String Extrinsic){
Flyweight flyweight = null;
if(pool.containsKey(Extrinsic)){
flyweight = pool.get(Extrinsic);
}else{
flyweight = new ConcreteFlyweight(Extrinsic);
pool.put(Extrinsic, flyweight);
}
return flyweight;
}
}
// 场景类
public class Client {
public void test() {
Flyweight weight = FlyweightFactory.getFlyWeight("ex-abc"); // 构建了一个对象
weight.setIntrinsic("in-abc"); // 设置它自己的内部状态
// 然后这个对象用完了,不需要了。又有一个内部状态是 “in-bcd"的了
Flyweight weight = FlyweightFactory.getFlyWeight("ex-abc");
weight.setIntrinsic("in-bcd");
// 如果用普通的 new 对象,内存里是同时有两个对象
// 但现在其实是一个对象,只不过修改了内部状态值
}
}
应用场景:
- 系统中存在大量的相似对象。
- 细粒度的对象都具备较接近的外部状态,而且内部状态与环境无关,也就是说对象没有特定身份。
- 需要缓冲池的场景。
虽然可以使用享元模式可以实现对象池,但是这两者还是有比较大的差异,对象池着重在对象的复用上,池中的每个对象是可替换的,从同一个池中获得 A对象和 B 对象对客户端来说是完全相同的,它主要解决复用,而享元模式在主要解决的对象的共享问题,如何建立多个可共享的细粒度对象则是其关注的重点。