反射
反射在有些地方看上去有点像是委托,但两者的差异还是蛮大的。委托的关键是编译器安全,而反射则是牺牲了编译时的安全检查,而带来了运行时的灵活性:它通过字符串来调用或取到指定的对象,而可以让程序在运行时获取或修改任何代码内容——本质上来说,反射是一种「元操作」,用代码来操作代码,也是字面意义上的「反射」。
就拿我之前写的排程场景来说:假设我的排程是子类继承,下级只关心具体的job,但如果我的场景是判断有多少个job继承了基类——目前的做法是用反射去扫。在我刚了解到委托机制后,我的设想是,能不能在基类里面采用生命周期管理的模式,给子类包在一个run里,排程实际运行的是run,然后基类定义一个事件,这个run就是——到这一步时,我就突然发现了——事实上在基类里预定义的委托属性,在每次被继承并实例化时,这个属性都会重置,那这样的话事件队列就空了。
因此启动时直接扫描程序本身,去确认有多少子类继承了这个基类,才能交给排程框架去统一注册。否则要知道job有多少,就得先获取job,要获取job就得先注册,注册就得知道到底有多少job——最终就是没有任何job会被注册。实例化之前框架就得知道有几个,那我不可能在这之后才让job进事件,所以必须在启动前就知道,那这个只能靠反射去扫有多少类继承了base。这是一个类型发现问题,而不是委托所承载的对象之间的交互(订阅者通过发布者暴露的委托来操作)问题。