关于回调:
java
回调是观察者模式以及反应堆模式的基础react
一句话,回调就是一种双向调用模式,什么意思呢,就是说,被调用方在被调用时也会调用对方,这就叫回调。“If you call me, i will call back”。
先看看这个能够说比较经典的使用回调的方式:算法
背景1:class A 实现接口inA设计模式
背景2:class A 中包含一个对于class B的引用b 网络
背景3:class B有一个参数为InA的方法test(InA a) 并发
class A的对象a调用B的方法传入本身(因为形参是个inA a),test(a) ——这一步至关于you call me.框架
而后b就能够在test方法中调用InA的方法(已经将形参:接口a的引用传入了) ——这一步至关于I call you back.异步
能够参考下面的代码:ide
//最基本的回调模式实现: public interface inA { public void callBacka(); } public class A implements inA{ //含有个B的实例 B b=new B(); @Override public void callBacka() { // TODO Auto-generated method stub System.out.println("excute the method in class A"); } } public class B { public void test(inA a){ a.callBacka(); } public void excuteB(){ System.out.println("excute the method in class B"); } }
能够看出来,A类能够经过a.b得到b的实例来调用b中的方法,执行完以后,在B类的对应方法中,能够经过传入的A的参数,来实现对于A的方法的回调,这个是很关键的。函数
回调还能够实现异步操做,好比说,你有一个复杂的问题解决不了,打电话给你的同窗,你的同窗说能够解决这个问题,可是须要一些时间,那么你不可能一直拿着电话在那里等,你会把你的电话号码告诉他,让他解决以后打电话通知你。回调就是体如今你的同窗又反过来拨打你的号码。
结合到前面所分析的,你打电话给你同窗就是【you call me】,你同窗解决完以后打电话给你就是回调【i call you back】。
两个关键点:
一、A类中包含一个B的引用,做为其属性
二、B类的须要回去到A的方法中,包含一个方法,这个方法的形参是对于A类的引用。
三、回调方法须要用接口实现,这样A能够经过集成接口,实现不一样类型的回调方式。
再总结一下:软件模块之间老是存在着必定的接口,从调用方式上,能够把他们分为三类:同步调用、回调和异步调用。同步调用是一种阻塞式调用,调用方要等待对方执行完毕才返回,它是一种单向调用;回调是一种双向调用模式,也就是说,被调用方在接口被调用时也会调用对方的接口;异步调用是一种相似消息或事件的机制,不过它的调用方向恰好相反(注意这个是与以前的的例子相反的),接口的服务在收到某种讯息或发生某种事件时,会主动通知客户方(即调用客户方的接口)。回调和异步调用的关系很是紧密,一般咱们使用回调来实现异步消息的注册,经过异步调用来实现消息的通知。(貌似仅仅是用途不一样而已 实质上差很少)同步调用是三者当中最简单的,而回调又经常是异步调用的基础。
观察者模式(Observer)
观察者模至关因而回调模式的扩充。在观察者模式中,观察者至关于上面例子中的A,被观察者至关于上面例子中的B。不一样的是有多个观察者,一个被观察者,也能够是多个。
观察者模式的官方定义:
观察者模式定义了对象间的一种一对多依赖关系,使得每当一个对象改变状态,则全部依赖于它的对象都会获得通知并被自动更新。
当一个被观察者的状态发生改变 全部依赖它的对象都发生变化。
该模式的几个角色:
Subject(被观察的对象接口 ),规定ConcreteSubject的统一接口。
每一个Subject能够有多个Observer,(经过在具体实现类中添加观察者引用的ArrayList或者其余相似方式来实现,这是实现回调方式的关键),观察者是先于被观察者建立的,而且要将对于观察者的引用加入到被观察者的ArrayList中,这样才能在被观察者的信息改变了以后通知对应的观察者。(由于观察者是先于被观察者而建立的 而最后要经过被观察者来调用观察者,进行信息的更新,即后建立的,反过来调用先建立的对象,因此是回调)
ConcreteSubject(具体被观察对象)
维护对全部具体观察者的引用的列表,状态发生变化时会发送通知给全部注册的观察者。(经过列表中对于obversor的引用,来是实现回调,更新观察者)
从功能上来说,ConcreteSubjec至少要包含 addobservor(添加一个观察者) deletobservor(删除一个观察者) 以及updateobservor三个部分,经过updateobservoer来进行回调,对观察者进行更新,或者是通知观察者来执行相对应的事务。
Observer(观察者接口)
规定ConcreteObserver的统一接口;
定义了一个update()方法,在被观察对象状态改变时会被调用。
ConcreteObserver(具体观察者)
维护一个对ConcreteSubject的引用,(这个能够经过对于ConcreteSubject进行引用,以此来调用ConcreteSubject中的方法,好比添加删除之类的操做,这样的话,不用在main函数中生成ConcreteSubject的具体的类了,每个observer都含有add delete的方法)
特定状态与ConcreteSubject同步,实现Observer接口,经过update()方法接收ConcreteSubject的通知。(回调过来的具体执行部分)
具体分析见下面的代码,将obversor写成了witcher。
//定义观察者接口 public interface iWatcher { public void update(String str); } //定义被观察者接口 public interface iSubject { public void add(iWatcher w); public void delete(iWatcher w); //修改观察者类中的信息 public void update(String str); } public class concreteWatcher implements iWatcher { private String str; private int id; public void setId(int id) { this.id=id; } public int getId(){ return id; } //构造函数 public concreteWatcher(String str,int id){ this.str=str; this.id=id; System.out.println("the str is created:"+str+this.getClass().hashCode()); } @Override public void update(String str) { // TODO Auto-generated method stub this.str=str; System.out.println(this.getId()+" the str is updated:"+str); } } public class concreteSubject implements iSubject{ //含有一个观察者的队列 list是观察者队列的引用 ArrayList<iWatcher>list=new ArrayList<iWatcher>(); @Override public void add(iWatcher w) { // TODO Auto-generated method stub list.add(w); } @Override public void delete(iWatcher w) { // TODO Auto-generated method stub list.remove(w); } //体现回调的是在这个地方 @Override public void update(String str) { // TODO Auto-generated method stub //因为List是自身类的属性 不用经过方法在去传了 //这里是一个回调 watcher中的方法去进行更新 for(iWatcher w :list){ w.update(str); } } } package com.designpatten.Observer; public class Test { //生成三个观察者 public static void main(String []args){ concreteWatcher a1=new concreteWatcher("watcher1",1); concreteWatcher a2=new concreteWatcher("watcher2",2); concreteWatcher a3=new concreteWatcher("watcher3",3); //生成一个被观者 即抽象主题 concreteSubject sub=new concreteSubject(); sub.add(a1); sub.add(a2); sub.add(a3); sub.update("update the information"); } } //执行结果 /* the str is created:watcher11580958233 the str is created:watcher21580958233 the str is created:watcher31580958233 1 the str is updated:update the information 2 the str is updated:update the information 3 the str is updated:update the information */
关于反应堆模式(reactor)
反应器模式(Reactor pattern)与观察者模式(Observer pattern)在这个方面极为类似:当一个主体发生改变时,全部依属体都获得通知。不过,观察者模式与单个事件源关联,而反应器模式则与多个事件源关联 。
Reactor Pattern 是一种为处理服务请求并发提交到一个或者多个服务处理程序的事件设计模式,当请求抵达后,服务处理程序使用多路分配策略,而后同步地派发这些请求至相关的请求处理程序。
Observer patten只是监听一个固定的主题,在reactor patten中,至关于subject的实现实例中同时包含了不一样的Aarrylist每一个对应一个事件,每个事件被触发,传到subject中,相对应的Arraylist中引用的类就会被更新(所谓的进行注册过的事件)
在reactor模式中,资料中经常会提到一个Hook Method 便是钩子方法,这个是模板模式的一部份内容,具体的能够参考一下后面列出的连接。
这里就是简单总结一下:
从模板模式的角度来看,方法被分红三类:具体方法,抽象方法,钩子方法。
一、具体方法就是咱们平时所写的最多见的最普通的方法。
二、抽象方法在java中就是abstract方法,就是所谓的继承,这个也比较常见。在一个执行过程当中几个函数的出现顺序一致,可是每一个步骤于在子类中可能有不一样的实现,就直接继承,迪对不一样的抽象类进行不一样的实现便可,这个的核心思想是在父类中提供了一个算法的框架,子类只能听从这个框架来,可是具体每一个步骤的实现上可能有差异。最典型的就是sort函数,每次排序时,能够自定义排序规则,这个可能会设计到具体不一样的领域,可是sort函数的整个实现的大的步骤,则是彻底固定的。
三、钩子方法其实就是反过来了,利用钩子方法,子类能够必定程度上影响父类的执行流程,钩子方法的返回结果一般为bool型变量,经常将父类中(模板方法)的某一个步骤放在if语句中,若是钩子方法返回true则执行,返回false则不执行。在子类中能够根据实际状况对钩子方法进行覆盖,并对其默认返回值进行修改,从而肯定合适的模板方法的执行流程,至关因而子类影响了父类(模板方法)的执行流程。
相关参考资料:
http://blog.csdn.net/pi9nc/article/details/23169357 ( 这个感受比较通俗 )
http://1025250620.iteye.com/blog/1378538
http://daimojingdeyu.iteye.com/blog/828696
http://blog.csdn.net/fengxinze/article/details/7319059(这个是翻译版本)
(确定是logserver对象先要生成 才能注册到initial dispatcher中 才能进行回调 说实话 对于例子中的get_handler 看得仍是有点晕晕乎乎 先记录在这里)
模板方法模式
http://blog.csdn.net/lenotang/article/details/2911246
http://blog.csdn.net/lovelion/article/details/8299927
其余各类网络资料