我们在bind(消费者)的时候,总是要实现onSuccess(T t), onError(Throwable throwable), onFinished()三个方法,但是大部分场景是不需要这么多的,能否只实现部分的消费者函数呢?
设计思路
定义一个新的 残缺消费者类型, post()时,把残缺消费者,转换为完整消费者即可
实践
1. 残缺消费者 接口
2. bind(残缺消费者的实现)
/**
* “订阅”【观察者---消费者: 事件的消费者】, 实质是消费代理类的容器中add
* @param observer
* @return
*/
@Override
public IPublisher<T> bind(OnObserver<T> observer) {
((IObserverProxy) onObserver).addObserver(observer);
return this;
}
/**
* “订阅”残缺的消费者(只实现部分函数), 实质是new一个完成的消费者,add代理类容器
* 1. 获取 action 的线程调度标示 和 延迟
* 2. new一个 完成的消费者,并设置为 动态调度方式
* 3. 消费者代理类的容器添加
* @param action1
* @return
*/
@Override
public IPublisher<T> bind(final Action1<T> action1) {
// 获取 action1 的 with Object.class参数的 的"call"方法 上的注解
final RunContextType type = AnnotationUtils.getRunContext(action1,"call",Object.class);
// 获取 action1 的 with Object.class参数的 的"call"方法 上的注解
final int delayms = AnnotationUtils.getDelayAnno(action1,"call",Object.class);
OnObserver<T> observer = new OnObserver<T>() {
public RunContextType runcontext = type;
public int delay = delayms;
// 使用动态 注解方式
// invoker的线程调度处,不再从该函数的注解上获取对应注解值,而是获取 该OnObserver中的对应字段
@RunContext(RunContextType.Dynamic)
@Override
public void onSuccess(T t) {
action1.call(t);
}
@Override
public void onError(Throwable throwable) {
}
@Override
public void onFinished() {
}
};
((IObserverProxy) onObserver).addObserver(observer);
return this;
}
2.1 (RunContextType.Dynamic)注解的实现
相比大家在bind()代码中也看到了, 我们是new 了一个完整的OnObserver, 面临的问题就是,新的OnObserver的函数注解,是不能动态生成的,因此出现了RunContextType.Dynamic方式
- 在OnObserver定义两个注解的对象实例
- Dynamic的线程调度方式,利用反射,获取 对象中的注解的实例(不再是Method上的注解)
private Future invoke_dynamic(Method method, Object object, Object... values) {
RunContextType type = null;
int delay = 0;
try {
Field field = object.getClass().getField(DynamicFlagname);
type = (RunContextType) field.get(object);
Field field1 = object.getClass().getField(DynamicFlagDelay);
delay = field1.getInt(object);
} catch (NoSuchFieldException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
if (type == null)
return null;
Future future = null;
switch (type){
case CurrentThread:
invoke_current_thread(method,object,delay,values);
break;
case CurrentLoop:
invoke_current_loop(method,object,delay,values);
break;
case NewThread:
invoke_new_thread(method,object,delay,values);
break;
case MainThread:
invoke_main_thread(method,object,delay,values);
break;
case MainLoop:
invoke_main_loop(method,object,delay,values);
break;
case Calculate:
invoke_calculate(method,object,delay,values);
break;
case IO:
invoke_io(method,object,delay,values);
break;
case NewHandlerThread:
invoke_new_handler_thread(method,object,delay,values);
break;
case Dynamic:
invoke_dynamic(method, object, values);
break;
}
return future;
}