序言
在学习Android的MVC结构时(android MVC和MVP探讨),对其中的回调机制不是很理解,查了很多资料,现在决定写一篇博客来加深一下印象。
首先我们想像一个场景,有一个厨房,里面有厨师小张和见习生小明。
第一章
客人点了一碗土豆腊肉,小张让小明自己炒,自己出去买烟去了。土豆腊肉对小明来说不是什么难事,自己就能搞定,于是用代码来写就是:
public class Student {
private String name = null;
public Student(String name) {
this.name = name;
}
public void setName(String name){
this.name = name;
}
public String Cooking(String a,String b){
return a.concat(b);
}
public void ordering(String a,String b) {
String result = Cooking(a,b);
System.out.print(name+"用铁锅将"+a+b+"煮熟成"+result);
}
}
测试代码:
public class Test1 {
public static void main(String[] args) {
Student s = new Student("小明");
String a="土豆";
String b="腊肉";
s.ordering(a, b);
}
}
结果:小明用铁锅将土豆腊肉煮熟成土豆腊肉
这里由Student类单独完成,没有使用回调
第二章
另一个客人来了,他想吃黄豆炖牛肉,就下单了。这下小明蒙了,炖牛肉需要高压锅,厨师长出去了,高压锅在哪里也不知道。只好去隔壁餐厅借锅了。
高压锅代码:
public class Cooker {
public String Cook(String a,String b) {
return a.concat(b);
}
}
这里小明要使用高压锅了,所以修改一下小明的代码:
public class Student {
private String name = null;
public Student(String name) {
this.name = name;
}
public void setName(String name){
this.name = name;
}
public String Cooking(String a,String b){
return a.concat(b);
}
public String userCooker(String a,String b) {
return new Cooker().Cook(a, b);
}
public void ordering(String a,String b) {
String result = userCooker(a,b);
System.out.print(name+"使用高压锅将"+a+"和"+b+"煮熟成"+result);
}
}
添加了一个用高压锅的方法。这里我们可以发现小明的一部分任务已经开始转移了。
第三章
这时候,那个客人刚走,又来了一个客人要土豆炖牛肉。小明刚把高压锅还回去,又要去借,这厨师小张怎么还不回来啊。小明心生一计,从旁边餐厅买一份土豆炖牛肉再卖给客人。这样自己可以趁老板不在玩会手机,又能上菜了。
这下小明不需要使用高压锅的方法了,只需要一个Help方法就可以了,把详细的任务推给了别人。
小明的代码如下:
public class Student {
private String name = null;
public Student(String name) {
this.name = name;
}
public void setName(String name){
this.name = name;
}
public void help(String a,String b) {
new Cooker().Cook(a, b, this);
}
public void ordering(String a,String b,String result) {
System.out.print(name+"使用高压锅将"+a+"和"+b+"煮熟成"+result);
}
}
这下高压锅是别人在使用了,做好后要把菜给小明,所以要告诉锅的主人,菜是小明的。
高压锅代码
public class Cooker {
public void Cook(String a,String b,Student name) {
String result = a.concat(b);
name.ordering(a, b,result);
}
}
测试代码:
public class Test3 {
public static void main(String[] args) {
Student s =new Student("小明");
Cooker c = new Cooker();
String a="土豆";
String b="牛肉";
s.help(a, b);
}
}
结果:小明使用高压锅将土豆和牛肉煮熟成土豆牛肉。
这里回调功能就正式登场了,小明的ordering()方法就是回调函数了。小明用help方法,把做的菜告诉他们并把自己(this)也告诉他们,调用他们餐厅的Cook方法,做好后,回调小明的ordering方法,将菜给客人。
第四章
这是第三家餐厅发现,他们家高压锅坏了,他们无意间看到小明经常去别的餐厅订餐来卖,于是他们也去有高压锅的餐厅订菜卖给客人了。(别问我怎么餐厅都没有高压锅,这只是个例子。别在意细节)
这时,那个有高压锅的餐厅看出了猫腻,于是为了方便大家,做了一个用高压锅帮人做菜的接口。这样可以帮小明做菜,又可以帮第三家做菜了。
接口代码:
public interface Job {
public void cook(String a,String b,String result);
}
然后把高压锅代码也改一下(因为之前要传入一个Student参数,现在要面向所有人):
public class Cooker {
public void Cook(String a,String b,Job person) {
String result = a.concat(b);
person.cook(a, b, result);
}
}
这里小明他们就只需要一个接口就可以做菜了:
public class Student {
private String name = null;
public Student(String name) {
this.name = name;
}
public void setName(String name){
this.name = name;
}
public class Cook1 implements Job {
@Override
public void cook(String a, String b, String result) {
System.out.println(name+"使用高压锅将"+a+"和"+b+"煮熟成"+result);
}
}
public void Help(String a ,String b) {
new Cooker().Cook(a, b,new Cook1());
}
}
第三家餐厅:
public class People {
private String name;
public People(String name) {
this.name=name;
}
public void setName(String name) {
this.name=name;
}
public class Cook2 implements Job{
@Override
public void cook(String a, String b, String result) {
// TODO Auto-generated method stub
System.out.println(name+"用高压锅将"+a+"和"+b+"煮熟成"+result);
}
}
public void Help(String a,String b) {
new Cooker().Cook(a, b, new Cook2());
}
}
测试程序如下:
public class Test3 {
public static void main(String[] args) {
Student s =new Student("小明");
People p = new People("第三方餐厅");
String a="土豆";
String b="牛肉";
String c="黄豆";
String d="排骨";
s.Help(a, b);
p.Help(c, d);
}
}
结果:
小明使用高压锅将土豆和牛肉煮熟成土豆牛肉
第三方餐厅用高压锅将黄豆和排骨煮熟成黄豆排骨
这里可以看出,高压锅的使用已经变成了一个业务,只要那食材来就可以帮忙加工。