消息驱动机制,也叫观察者模式、事件驱动模式。不论是在应用还是游戏中,都是一种常见的设计模式,该设计模式非常利于模块的解耦。

我们这里以老师和学生为例,有一个老师和多个学生,老师发的每一个消息,学生都要能够收到。如:老师说,明天我们放假,然后确保所有学生都能收到该消息。

首先,建立一个消息分发中心,负责收集和移除消息接收个体(这里就是学生),同时负责通知到收集的每一个个体。该类命名为Human_Event.

public abstract class Human_Event {
	
	private List<Listener> mNoticeList = new ArrayList<Listener>();
	
	
	public void addListener(Listener msg) {
		mNoticeList.add(msg);
	}
	
	public void removeMessage(Listener msg) {
		mNoticeList.remove(msg);
	}
	
	public void notifyListener(String saySomething) {
		for (Listener l:mNoticeList) {
			l.update(saySomething);
		}
	}
	
	
	
}
然后,建立一个老师类,该类具有消息分发的特性,所以继承自Human_Event

public class Teacher extends Human_Event {
	
	private String mSomeWord;
	
	public String getSomeWord() {
		return mSomeWord;
	}
	
	public void say(String saySomething) {
		mSomeWord = saySomething;
		System.out.println("老师说:" + saySomething);
		this.notifyListener(saySomething);
	}
	

}
ok,消息中心就建立了。

然后,我们需要建立监听者,这建立一个接口类Listener

public interface Listener {
	public void update(String saySomething) ;
}
学生具有监听者的特性,所以继承自Listener

public class Student implements Listener {

	@Override
	public void update(String saySomething) {
		System.out.println("学生收到了消息:" + saySomething);
	}

}
ok,消息分发者和监听者都建立好了 ,现在来实现逻辑。

public class Client {

	public static void main(String[] args) {
		Teacher teacher = new Teacher();
		Student stu1 = new Student();
		Student stu2 = new Student();
		
		teacher.addListener(stu1);
		teacher.addListener(stu2);
		
		teacher.say("明天放假一天!");
		
		teacher.removeMessage(stu2);
		teacher.say("跟你们开玩笑的!");
	}
}

这里将监听者sut1 和stu2添加到事件中心,当老师say的时候,其他监听者就能收到消息啦。

上面这种消息模式,对于学生来说,是一种被动接收的过程,需要等待老师的saySomething参数传过来,其实我们这里可以做一个小小的变动,就可以变成主动拉取啦。

变动是这样的,将传给学生的对象不再是String,而是老师这个对象,如此,学生就可以取到老师的所有信息了。

第一处修改,修改Listener接口:

public interface Listener {
	public void update(Human_Event event) ;
}
第二处修改,修改消息派发处Human_Event类的传递参数为自身,删除notifyListener方法的参数:

public abstract class Human_Event {

	 private List<Listener> mNoticeList = new ArrayList<Listener>();  
     
    public void addListener(Listener msg) {  
        mNoticeList.add(msg);  
        System.out.println("添加一个学生。");
    }  
      
    public void removeMessage(Listener msg) {  
        mNoticeList.remove(msg);  
        System.out.println("移除一个学生。");
    }  
      
    public void notifyListener() {  
        for (Listener l:mNoticeList) {  
            l.update(this);  
        }  
    } 
}
如此,将整个Teacher对象传给了Student,Student就可以根据自己的需要去取老师的信息了。

但是,个人比较推荐前者,按需将参数传递过去就行了,将整个对象传递过去并进行强转,对于受体来说,就可以毫无节制的获取所有信息了,可能造成进一步耦合。








Logo

北京人形旗下天工造物具身智能开源社区,聚焦具身天工与慧思开物两大平台

更多推荐