观察者模式与监听器模式

1.观察者模式  

在观察者模式结构图中包含如下几个角色:

      ● Subject(目标):目标又称为主题,它是指被观察的对象。在目标中定义了一个观察者集合,一个观察目标可以接受任意数量的观察者来观察,它提供一系列方法来增加和删除观察者对象,同时它定义了通知方法notify()。目标类可以是接口,也可以是抽象类或具体类。

 要素:1.包含观察者集合存储观察者对象,并提供对该对象的增加和删除方法。

            2.定义通知方法notify()。

      ● ConcreteSubject(具体目标):具体目标是目标类的子类,通常它包含有经常发生改变的数据,当它的状态发生改变时,向它的各个观察者发出通知;同时它还实现了在目标类中定义的抽象业务逻辑方法(如果有的话)。如果无须扩展目标类,则具体目标类可以省略。

      ● Observer(观察者):观察者将对观察目标的改变做出反应,观察者一般定义为接口,该接口声明了更新数据的方法update(),因此又称为抽象观察者。

      ● ConcreteObserver(具体观察者):在具体观察者中维护一个指向具体目标对象的引用,它存储具体观察者的有关状态,这些状态需要和具体目标的状态保持一致;它实现了在抽象观察者Observer中定义的update()方法。通常在实现时,可以调用具体目标类的attach()方法将自己添加到目标类的集合中或通过detach()方法将自己从目标类的集合中删除。

      观察者模式描述了如何建立对象与对象之间的依赖关系,以及如何构造满足这种需求的系统。观察者模式包含观察目标和观察者两类对象,一个目标可以有任意数目的与之相依赖的观察者,一旦观察目标的状态发生改变,所有的观察者都将得到通知。作为对这个通知的响应,每个观察者都将监视观察目标的状态以使其状态与目标状态同步,这种交互也称为发布-订阅(Publish-Subscribe)。观察目标是通知的发布者,它发出通知时并不需要知道谁是它的观察者,可以有任意数目的观察者订阅它并接收通知。

1.抽象目标类

import java.util.*;
abstract class Subject {
    //定义一个观察者集合用于存储所有观察者对象
protected ArrayList observers<Observer> = new ArrayList();
 
//注册方法,用于向观察者集合中增加一个观察者
	public void attach(Observer observer) {
    observers.add(observer);
}
 
    //注销方法,用于在观察者集合中删除一个观察者
	public void detach(Observer observer) {
    observers.remove(observer);
}
 
    //声明抽象通知方法
	public abstract void notify();
}

2.具体目标类

class ConcreteSubject extends Subject {
    //实现通知方法
	public void notify() {
        //遍历观察者集合,调用每一个观察者的响应方法
		for(Object obs:observers) {
			((Observer)obs).update();
		}
	}	
}

3.抽象观察者

interface Observer {
    //声明响应方法
	public void update();
}

4.具体观察者

class ConcreteObserver implements Observer {
    //实现响应方法
	public void update() {
		//具体响应代码
	}
}

2.监听器模式

一文带你搞懂监听器的作用及servlet中提供的监听器_是庸医啊的博客-CSDN博客

1.被监听者状态的改变被定义为一个对象,称为事件。
2.被监听器对象称为事件源
3.对监听器的通知称为触发监听器

1.定义事件源

//定义事件源(类似被观察者)
public interface IListenerable{
	 //注册监听器
	 void setListener(IListener listener);
	 //触发监听器
	 //与被观察模式比较(此时传递的是事件,而不是一个字符串)
	 void triggerListener(ICurdEvent);
	 }

2.定义事件接口

注意:一般情况下,监听器对象被事件触发后,都会从事件中
获取事件源对象,然后在从事件源中获取一些数据,所以说
一般事件对象中会提供事件源对象的方法(事件对象还可以提
供其它数据,以便监听器获取)
------------------------------------------------
//定义事件接口
public interface ICurdEvent{
   //声明事件类型(增删改查)
   String CRE_EVENT = "create event";
   String UPD_EVENT = "update event";
   String RET_EVENT = "retrieve event";
   String DEL_EVENT = "delete event";
   //获取事件源
   IListenerable getEventSource();
   //获取事件类型
   String getEventType();
}

3.定义监听器接口

public interface IListener{
	//处理事件
	void handle(ICurdEvent event);
}

4.监听器接口实现类

public class Listener implements IListener {

	@Override
	public void handle(ICurdEvent event) {
		//获取事件的事件类型
		String eventType = event.getEventType();
		if(ICurdEvent.CRE_EVENT.equals(eventType)) {
			System.out.println("监听器执行增加操作");
		}else if(ICurdEvent.DEL_EVENT.equals(eventType)) {
			System.out.println("监听器执行删除操作");
		}else if(ICurdEvent.UPD_EVENT.equals(eventType)) {
			System.out.println("监听器执行修改操作");
		}else if(ICurdEvent.RET_EVENT.equals(eventType)) {
			System.out.println("监听器执行查找操作");
		}
	}
}

5.定义事件源接口的实现类

public class EventSource implements IListenerable {

	private IListener listener;
	//注册事件源
	@Override
	public void setListener(IListener listener) {	
		this.listener = listener;
	}
   //触发事件源
	@Override
	public void triggerListener(ICurdEvent event) {
	  listener.handle(event);	
	}
	//事件源的业务逻辑代码(实际开发中)
	public void deleteStudent(){
	//业务逻辑...
	//获取事件
	ICurdEvent event = new CurdEvent(this,"deleteStu");
	this.triggerListener(event);
}

}

6.事件接口的实现类

//定义事件的实现类
public class CurdEvent implements ICurdEvent {
	private IListenerable eventSource;
	private String methodName;
	//通过构造方法来获取事件类型和事件源对象
	public CurdEvent(IListenerable eventSource, String methodName) {
		super();
		this.eventSource = eventSource;
		this.methodName = methodName;
	}

	@Override
	public IListenerable getEventSource() {
	 //返回事件源对象
		return eventSource;
	}

	@Override
	public String getEventType() {
	//根据不同的事件类型返回不同的值
		String eventType = null;
		if(methodName.startsWith("save")) {
			eventType = CRE_EVENT;
		}else if(methodName.startsWith("delete")) {
			eventType = DEL_EVENT;
		}else if(methodName.startsWith("update")) {
			eventType = UPD_EVENT;
		}else if(methodName.startsWith("find")) {
			eventType = RET_EVENT;
		}else {
			eventType = "no this method";
		}
		return eventType;
	}
}

7.测试类

public class Test {
	public static void main(String[] args) {
		//定义监听器
		IListener listener = new Listener();
		//定义事件源
		EventSource some = new EventSource();
		//注册监听器
		some.setListener(listener);
		//执行事件源的业务逻辑让相应的监听器做出动作
		some.deleteStudent();//执行该逻辑触发监听器
	}
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值