关于回调函数的理解,以及观察者模式,代理模式

今天在学习Android的时候,突然看到“回调函数”这个关键字,但是却在脑海中找不到相应的映射。于是去一些CSDN博客上恶补了关于回调函数的知识。

后来为了加深理解,编写了3个例子(第一个是纯回调函数;第二个是观察者模式,里面应用了回调函数的思想;第三个是代理模式,也和回调很类似),现在记录我今天的学习。

第一部分:关于回调函数的理解(具体定义网上都类似,我这里用编程来实践)

定义一个程序A类:

public class A {
	//定义回调对象,因为实现回调函数的具体类肯定会实现CallBackInterface接口
	//所以将回调对象的类型设为接口类型
	private CallBackInterface cbInterface;
	//设置回调对象的函数
	public void setCallFunc(CallBackInterface cbInterface)
	{
		this.cbInterface=cbInterface;
	}
	//调用回调函数,回调函数在回调接口里面预留
	public void call()
	{
		//通过回调对象调用回调函数
		if(cbInterface!=null)//为了程序更加严谨
		{
		cbInterface.callBack();
		}
	}
}
定义A类里面的回调接口:

/**回调接口里面定义回调函数*/
public interface CallBackInterface {
	public void callBack();
}

定义一个程序B类(实现回调接口):

/**具体实现回调函数的类*/
public class B implements CallBackInterface{
	@Override
	public void callBack() {
		//回调函数具体的实现
		System.out.println("具体回调函数的实现,由B类来实现!");
	}
}

测试类:

/**测试回调函数的程序入口*/
public class Test {
	public static void main(String[] args) {
		/**方法一,回调函数具体的实现类B类是一个具体的类*/
		A a1=new A();
		B b1=new B();
		a1.setCallFunc(b1);
		a1.call();
		/**方法二,回调函数具体的实现由匿名类完成*/
		A a2=new A();
		a2.setCallFunc(new CallBackInterface() 
		{
			//匿名类的回调函数实现方法
			@Override
			public void callBack() {
				System.out.println("由匿名类实现A的回调函数!");
			}		
		});
		a2.call();
		}
}

效果图:

总的来说:先定义一个回调接口(里面声明回调函数),然后程序B实现该接口,定义具体的函数的内容,最后程序A里面添加回调对象B。这时就可以通过A的函数来调用B里面的回调方法(实际上还是A里面通过B的对象来调用B的方法)

第二部分:观察者模式(因为观察者模式应用了回调函数的思想)

定义抽象的主题角色:

//抽象的主题角色---抽象的被观察对象,里面生命方法(移除,添加,通知观察者)
public interface Watched {
    public void addWatcher(Watcher watcher);
    public void removeWatcher(Watcher watcher);
    public void notifyWatchers(String str);
}

定义抽象的观察者:

//抽象的观察者
public interface Watcher {
	public void update(String str);
}

定义具体的主题角色:

//定义具体的主题对象,类似与回调例子中的A类
public class ConcreteWatched implements Watched{
	//存放观察者
	private List<Watcher> list=new ArrayList<Watcher>();
	@Override
	public void addWatcher(Watcher watcher) {
		list.add(watcher);
	}

	@Override
	public void removeWatcher(Watcher watcher) {
		list.remove(watcher);
	}
	//这个函数相当于A类里面的call()函数,用来调用回调函数update(String str)
	@Override
	public void notifyWatchers(String str) {
		for(Watcher watcher:list)
		{
			//调用回调函数
			watcher.update(str);
		}
	}

}

定义具体的观察者:

//定义具体的观察者---类似与回调函数例子中的B类(实现具体的回调功能),这里面update(String str)就是一个回调函数
public class ConcreteWatcher implements Watcher{
	@Override
	public void update(String str) {
		//具体功能的实现,这里只是简单的输出
		System.out.println(str);
	}
}
测试程序:

/**测试观察者模式的程序入口*/
public class Test {

	public static void main(String[] args) {
		//添加主题对象-用来调用回调函数
        Watched watched_01 = new ConcreteWatched();
        //添加观察者-用来定义回调函数的具体实现
        Watcher watcher_boy1 = new ConcreteWatcher();
        Watcher watcher_boy2 = new ConcreteWatcher();
        Watcher watcher_boy3 = new ConcreteWatcher();
        //主题对象添加对应的观察者-添加回调对象
        watched_01.addWatcher(watcher_boy1);
        watched_01.addWatcher(watcher_boy2);
        watched_01.addWatcher(watcher_boy3);
        //主题对象通知所有的观察对象-调用回调函数
        watched_01.notifyWatchers("开心");
	}
}

效果图:

第三部分:代理模式(注意大致思路)

大致理解:C需要B的服务,而B通过安排A给C提供服务。其中B是被代理者(委托人),被代理类主要是接活,以及交给代理者去干活。而代理类和被代理类本身实现同一个接口。

这里以项目经理安排程序员给客户提供服务为例子

声明被代理类与代理类的共同接口(共同技能):

//抽象角色-程序员,声明被代理对象和代理对象的共同接口
public interface KindProgrammer {
	//共同的技能编程
	//不同之处在于,CodeProgrammer是自己编程,而ProjectManager是安排CodeProgrammer编程
	public void programing();
}

定一个个具体的代理类(具体编程人员):

/**定义一个具体的代理类---具体编写程序的程序员*/
public class CodeProgrammer implements KindProgrammer{
	//这个方法类似与回调函数,由CodeProgrammer具体实现,
	//由ProjectManager通过调用CodeProgrammer对象来执行.
	//与回调函数有点区别的就是,在那个回调实例中,A类没有必要和B类实现同一个接口
	@Override
	public void programing() {
		System.out.println("我是一名程序员,我正在编程!");
	}
}

定一个具体的被代理类(委托类,项目经理):

/**定义一个被代理类,即委托人(接活的经理)*/
public class ProjectManager implements KindProgrammer{
	//定义代理对象
	private KindProgrammer kindProgrammer;
	//设置具体的代理对象
	public void setAgency(KindProgrammer kindProgrammer)
	{
		this.kindProgrammer=kindProgrammer;
	}
	//实现具体的方法,实际上是通过代理对象来实现具体的功能
	@Override
	public void programing() {
		System.out.println("我是一名项目经理,现在我安排一个程序员编程!");
		//其实这里用到了多态
		if(kindProgrammer!=null)//为了程序更加严谨
		{
		this.kindProgrammer.programing();
		}
	}	
}

测试程序(客户):

/**代理模式例子的入口,从客户需求出发*/
public class Client {
	public static void main(String[] args) {
		//客户的一个项目需要项目经理编程实现
		//现在先找到对应的项目经理
		ProjectManager projectManager=new ProjectManager();
		//项目经理安排一个程序员来编程完成该项目
		projectManager.setAgency(new CodeProgrammer());
		//表面上是项目经理编程,实际是程序员在编程
		projectManager.programing();
	}

}
效果图:


总结:通过编程实践,对回调函数的理解更加深刻了。

一下是完整工程的链接:http://download.csdn.net/detail/u010979495/8064967

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值