Java设计模式-观察者模式

工程结构

在这里插入图片描述

谷歌的观察者模式框架

package jpattern.observer.guava;

import com.google.common.eventbus.EventBus;

//谷歌的观察者模式框架
public class GuavaEventTest {

	public static void main(String[] args) {
		EventBus eventBus = new EventBus();
		GuavaEvent gEvent = new GuavaEvent();
		eventBus.register(gEvent);
		eventBus.post("AA 124 %#$#");
	}

}

package jpattern.observer.guava;

import com.google.common.eventbus.Subscribe;

public class GuavaEvent {

	@Subscribe
	public void subscribe(String str) {
		//业务逻辑
		System.out.println("执行subscribe()方法,传入参数为:"+str);
	}
}

基于
java.util.Observable;
java.util.Observer;

package jpattern.observer.mall;

import java.util.ArrayList;
import java.util.List;
import java.util.Observable;
import java.util.Observer;

public class ProductList extends Observable{
	
	private List<String> productList = null;//产品列表
	
	private static ProductList instance = null;
	
	//私有构造方法
	private ProductList() {
		
	}
	//单例模式
	public static ProductList getInstance() {
		if (instance == null) {
			instance = new ProductList();
			instance.productList = new ArrayList<String>();
		}
		return instance;
	}
	//增加多个观察者
	public void addAllPListObserver(Observer ... args) {
		for (Observer observer : args) {
			this.addObserver(observer);
		}
		
	}

	public void addProduct(String productName) {
		productList.add(productName);
		System.out.println("产品列表新增产品"+productName);
		//设置被观察对象发生变化
		this.setChanged();
		//通知观察者,并传递新产品
		this.notifyObservers(productName);
	}
}

package jpattern.observer.mall;

import java.util.Observable;
import java.util.Observer;

public class Mall1Observer implements Observer{

	@Override
	public void update(Observable o, Object product) {
		String p = (String) product;
		System.out.println("Mall1发布新产品:"+p);
		
	}

}

package jpattern.observer.mall;

import java.util.Observable;
import java.util.Observer;

public class Mall2Observer implements Observer{

	@Override
	public void update(Observable o, Object product) {
		String p = (String) product;
		System.out.println("Mall2发布新产品:"+p);
		
	}

}

package jpattern.observer.mall;
//测试
public class ObserverTest {

	public static void main(String[] args) {
		ProductList observable = ProductList.getInstance();
		
		Mall1Observer observer1 = new Mall1Observer();
		Mall2Observer observer2 = new Mall2Observer();
		
		observable.addAllPListObserver(observer1,observer2);
		
		observable.addProduct("KK自行车");
		observable.addProduct("KK电脑");
	}

}

小结

//--------------------也就是下面被执行后
//设置被观察对象发生变化
		this.setChanged();
		//通知观察者,并传递新产品
		this.notifyObservers(productName);

//--------------这个方法自动重写(执行)
@Override
	public void update(Observable o, Object product) {
		String p = (String) product;
		System.out.println("XX发布新产品:"+p);
		
	}

下面是Spring5核心原理与30个手写实战的代码里面
Spring5核心原理与30个手写实战的代码 百度百科

package jpattern.observer.mouse;

import java.lang.reflect.Method;

//监听器的一种包装,标准事件源格式的定义
public class Event {

	//事件源,事件是由谁发起的
	private Object source;
	//事件触发,要通知谁
	private Object target;
	//事件触发,要做什么工作,回调
	private Method callBack;
	//事件的名称,触发什么事件
	private String trigger;
	//事件触发时间
	private long time;
	
	
	//构造方法 
	/**
	 * 
	 * @param target 事件触发,要通知谁
	 * @param callBack 事件触发,要做什么工作,回调
	 */
	public Event(Object target, Method callBack) {
		this.target = target;
		this.callBack = callBack;
	}
	
	//
	public Event setSource(Object source) {
		this.source = source;
		return this;
	}
	//
	public Event setTime(long time) {
		this.time = time;
		return this;
	}
	//
	public Event setTrigger(String trigger) {
		this.trigger = trigger;
		return this;
	}
	
	
	public Object getSource() {
		return source;
	}
	public Object getTarget() {
		return target;
	}
	public void setTarget(Object target) {
		this.target = target;
	}
	public Method getCallBack() {
		return callBack;
	}
	public void setCallBack(Method callBack) {
		this.callBack = callBack;
	}
	public String getTrigger() {
		return trigger;
	}
	
	public long getTime() {
		return time;
	}

	@Override
	public String toString() {
		return "Event [source=" + source + ", target=" + target + ", callBack=" + callBack + ", trigger=" + trigger
				+ ", time=" + time + "]";
	}
	
	
}

package jpattern.observer.mouse;

import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;

//提供事件注册和触发
public class EventLisenter {

	//JDK的底层lisenter通常也是这么设计的
	protected Map<String, Event> events = new HashMap<String, Event>();
	
	//添加事假类型和事件对象
	//通过事件名称和一个目标对象来触发事件
	/**
	 * 
	 * @param eventType
	 * @param target
	 */
	public void addLisenter(String eventType,Object target) {
		try {
			//调用本类的方法
			this.addEventLisenter(eventType, 
					target,
					target.getClass().getMethod("on"+toUpperFirstCase(eventType), 
							Event.class)
					
					);
			
		} catch (Exception e) {
			// TODO: handle exception
		}
	}
	
	/**
	 * 添加事件监听
	 * @param eventType
	 * @param target 事件触发,要通知谁
	 * @param callback 事件触发,要做什么工作,回调
	 */
	private void addEventLisenter(String eventType,Object target,Method callback) {
		//注册事件
		events.put(eventType, new Event(target, callback));
	}
	
	
	/**
	 * 内部私有触发方法,只要有动作就触发
	 * @param event 
	 */
	private void trigger(Event event) {
		//事件源
		event.setSource(this);
		//触发时间
		event.setTime(System.currentTimeMillis());
		try {
			//如果Method(回调)不为空,则发起回调
			if (event.getCallBack() != null) {
				//用反射调用它的回调函数
				//target:事件触发,要通知谁
				// java.lang.reflect.Method
				// Method.invoke
				event.getCallBack().invoke(event.getTarget(), event);
			}
		} catch (Exception e) {
			// TODO: handle exception
		}
	}
	
	/**
	 * 事件名称触发,用protected修饰符是给子类使用
	 * @param trigger
	 */
	protected void trigger(String trigger) {
		//如果HashMap不包含名称为trigger的Event
		if (!this.events.containsKey(trigger)) {
			return;
		}
		//调用参数是事件类型的触发方法
		//从HashMap根据名称获取Event,再设置名称(trigger)
		trigger(this.events.get(trigger).setTrigger(trigger));
	}
	
	/**
	 * 逻辑处理的私有方法,首字母大写
	 * @param str
	 * @return
	 */
	private String toUpperFirstCase(String str) {
		char[] chars = str.toCharArray();
		chars[0] -=32;
		return String.valueOf(chars);
	}
}

package jpattern.observer.mouse;

public class Mouse extends EventLisenter{
	//
	public void click() {
		System.out.println("调用click()方法");
		//根据事件名称调用继承来的 trigger(..) 方法
		this.trigger(MouseEventType.ON_LICK);
	}
	//

	public void onUp() {
		System.out.println("调用onUp()方法");
		this.trigger(MouseEventType.ON_UP);
		
	}
}

package jpattern.observer.mouse;

//事件回调方法,真正要处理的事件
public class MouseEventCallback {
	//单击方法
	public void onClick(Event e) {
		System.out.println("触发鼠标单击事件"+e);
		
	}
	//
	public void onUp(Event e) {
		System.out.println("触发鼠标弹起事件"+e);
	}
}

package jpattern.observer.mouse;

public class MouseEventTest {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		try {
			MouseEventCallback callback = new MouseEventCallback();
			//注册事件
			Mouse mouse = new Mouse();
			
			//事件注册
			mouse.addLisenter(MouseEventType.ON_LICK, callback);
			//调用方法
			mouse.click();
			
			//事件注册
			mouse.addLisenter(MouseEventType.ON_UP, callback);
			//调用方法
			mouse.onUp();
//			打印
//			调用单击方法
//			触发鼠标单击方法Event [source=jpattern.observer.mouse.Mouse@6d06d69c, target=jpattern.observer.mouse.MouseEventCallback@7852e922, callBack=public void jpattern.observer.mouse.MouseEventCallback.onClick(jpattern.observer.mouse.Event), trigger=click, time=1573447874787]

		} catch (Exception e) {
			// TODO: handle exception
		}
	}

}

package jpattern.observer.mouse;

//鼠标事件类型
public interface MouseEventType {
	//单击
	String ON_LICK = "click";
	
	//双击
	
	//弹起
	String ON_UP = "up";
}

这个使用了Java反射

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值