Java 实现

Java 实现,第1张

Java 实现委托+事件
  • 一、举例:猫和老鼠(委托与事件)
  • 二、Java实现C#中的委托和事件:
    • 1、委托类:
    • 2、事件类:
    • 3、被委托者:Cat猫类
    • 4、委托者:Mouser1,Mouser2老鼠类
    • 5、客户端:Client
    • 6、运行结果:

上篇提到了观察者模式的实现依赖倒转原则,尽管已经实现了依赖倒转原则,但“抽象通知者”,还是依赖“抽象观察者”,也就是说万一没有了抽象观察者这样的接口,通知功能就完成不了。另外就是每一个观察者,它不一定都需要接收到通知的。



知识补充:


委托是对函数的封装,可以当作给方法的特征指定一个名称。而事件则是委托的一种特殊形式,当发生有意义的事情时,事件对象处理通知过程)


什么是事件?
在C#中,事件就是一个宽泛的、无具体实现的事情,事件是宽泛的、只代表概念而不代表实现,具体的事件触发是通过委托调用实现方法来。


一、举例:猫和老鼠(委托与事件

1、建一个控制台应用系统:
我们的需求:有一个猫叫Tom,有两只老鼠叫Jerry和Jack,Tom只要一叫“喵,我是Tom”,两只老鼠就说“老猫来了,快跑”。

2、分析需要几个类以及类和类之间的关系:
当Cat的Shout方法触发时,老鼠Mouse就执行Run方法。不过这里如何用Shout触发让Mouse就执行Run方法。由于猫是不认识老鼠的,所以不能在Cat类中引用Mouse对象。

这时,就用到了委托事件的方法了。


二、Java实现C#中的委托和事件:

1、委托类:

委托是一种引用方法的类型。一旦委托分配了方法,委托将与该方法具有完全相同的行为。

package 猫和老鼠_委托;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
//委托类
public class Delegate {
	private Object obj;
	private String methodName;
	private Object[] methodParameter;
	private Class<?>[] methodType;
	public Delegate(){}
	
	public Delegate(Object obj, String methodName, Object...methodParameter) {
		this.obj = obj;
		this.methodName = methodName;
		this.methodParameter = methodParameter;
		int len=methodParameter.length;
		this.methodType = new Class[len];
		for(int i=0;i<len;i++){
			methodType[i]=methodParameter[i].getClass();
		}
	}
	public void invoke() throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException{
		Method m=obj.getClass().getDeclaredMethod(methodName, methodType);
		m.invoke(obj, methodParameter);
	}
	
}

2、事件类:
package 猫和老鼠_委托;

import java.lang.reflect.InvocationTargetException;
import java.util.Vector;
//事件
public class Event {
	private Vector<Delegate> vs=new Vector<Delegate>();
	
	public void invoke() throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException{
	for(Delegate d:vs){
			d.invoke();
		}
	}
	public void addDelegate(Delegate delegate){
		System.out.println(delegate.toString());
		vs.add(delegate);
	}
	public void delDelegate(Delegate delegate){
		vs.remove(delegate);
	}
}

3、被委托者:Cat猫类
package 猫和老鼠_委托;

import java.lang.reflect.InvocationTargetException;

public class Cat {
	private String name;
	private Event event;
	public Cat(String name){
		this.name=name;
		event =new Event();
	}
	
	public  void addDelegate(Object obj, String methodName, Object...methodParameter){
		Delegate d=new Delegate(obj,methodName, methodParameter);
		event.addDelegate(d);
	}
	public void delDelegate(Object obj, String methodName, Object...methodParameter){
		Delegate d=new Delegate(obj, methodName, methodParameter);
		event.delDelegate(d);
	}
	public void action() throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException{
		System.out.println("我是"+name+",我来抓老鼠了!");
		event.invoke();
	}
}

4、委托者:Mouser1,Mouser2老鼠类
package 猫和老鼠_委托;
//委托者
public class Mouse1 {
	private String name;
	public Mouse1(String name){
		this.name=name;
	}
	public void shout(String name){
		System.out.println(name+"来了,我是"+this.name+",我要快跑!");
	}
}

package 猫和老鼠_委托;

public class Mouse2 {
	private String name;
	public Mouse2(String name){
		this.name=name;
	}
	public void speak(String name){
		System.out.println(name+"来了,我是"+this.name+",我要快跑!");
	}
}

5、客户端:Client
package 猫和老鼠_委托;

import java.lang.reflect.InvocationTargetException;

public class Client {

	public static void main(String[] args) throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
		// TODO Auto-generated method stub
		Cat cat=new Cat("Tom");
		Mouse1 m1=new Mouse1("Jerry");
		Mouse2 m2=new Mouse2("Jack");
		
		cat.addDelegate(m1, "shout", "Tom");
		cat.addDelegate(m2, "speak", "Tom");
		cat.action();
	}

}

6、运行结果:

这样就相当于c#的委托了,这样也改掉了观察者模式的缺点,通知者类完全不知道自己需要通知的是谁,做到了完全解耦,同时也去掉了抽象的观察者类。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/921314.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-16
下一篇 2022-05-16

发表评论

登录后才能评论

评论列表(0条)

保存