技术问答-24 如何实现观察者模式

参考自己之前的博客 忘得差不多了
https://blog.csdn.net/qq_36291682/article/details/74162673

一、Java实现观察者模式 用java提供的Observable Observer:

package com;

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

/**
 * 被通知的对象
 * @author Administrator
 *
 */
public class User implements Observer {
	private String name;

	public User(String name) {
		this.name = name;
	}

	public void update(Observable o, Object arg) {
		System.out.println("抢票用户"+name + arg+"有票了:");
	}

}

package com;

import java.util.Observable;

/**
 * 被观察者
 * @author Administrator
 *
 */
public class OfficialAccount extends Observable {
	public void publishNewInfo(String info) {
		setChanged();
		notifyObservers(info);
	}
}

package com;
/**
 * 测试
 * @author Administrator
 *
 */
public class Test {

	public static void main(String[] args) {

		// 被观察的角色
		OfficialAccount officialAccount = new OfficialAccount();
		// 观察者
		User userliu = new User("小刘");
		User userli = new User("小李");
		User userbai = new User("小白");

		// 将观察者注册到可观察对象的观察者列表中
		officialAccount.addObserver(userliu);
		officialAccount.addObserver(userli);
		officialAccount.addObserver(userbai);

		// 发布消息
		officialAccount.publishNewInfo("k123");
		//小刘抢了k123 不用再抢了
		officialAccount.deleteObserver(userliu);
		
		//
		officialAccount.publishNewInfo("D345");

	}

}

二、观察者模式解释



  • 观察者模式:有时又被称为发布(publish )-订阅(Subscribe)模式、模型-视图(View)模式、源-收听者(Listener)模式或从属者模式,是软件设计模式的一种
  • 在此种模式中,一个目标物件管理所有相依于它的观察者物件(说白了就是我被观察了 我还得管着观察我的人 真心累!),
  • 被观察者本身的状态改变时主动发出通知(你望远镜看着我 我动了一下 我还要打电话告诉你 我动了! )。
  • 被观察者通常通过调用各观察者所提供的方法来实现(我 需要打你电话 还得是你的电话号码)。
  • 此种模式通常被用来实现事件处理系统


三、 自己实现观察者模式

我的总结:观察者模式就是 被观察的人把所有观察他的人存起来 一旦自己状态变了之后 就挨个通知观察他的人
自己写一个的话 就是
一个被观察者类 (1) 存储所有他的观察者 (2)状态改变方法 (3) 通知观察者方法
一个观察者类 (1) 有一个方法 给被观察者调用

package com;

/**
 * 观察者
 * 
 * @author Administrator
 *
 */
public class Guancha {
	public Guancha(String name) {
		this.name = name;
	}

	private String name;

	/**
	 * 这是一个被调用的方法 当被观察者状态变化之后 就会调用所有他的观察者的这个方法
	 */
	public void update(String str) {
		System.out.println(name + ":收到被观察者的通知!   " + "被观察者状态:" + str);
	}
}

package com;

import java.util.ArrayList;
import java.util.List;

/**
 * 被观察者
 * 
 * @author Administrator
 *
 */
public class BeiGuancha {
	// 被观察者的状态
	private String state;

	// 存储他所有的观察者
	List<Guancha> guanchazhes;

	public BeiGuancha() {
		guanchazhes = new ArrayList<Guancha>();
	}

	// 添加观察者
	public void addGuancha(Guancha g) {
		guanchazhes.add(g);
	}

	// 通知所有观察者
	public void notifyAllGuancha() {
		for (Guancha g : guanchazhes) {
			g.update(state);
		}
	}

	public String getState() {
		return state;
	}

	public void setState(String state) {
		this.state = state;
	}

}

package com;

/**
 * 测试
 * 
 * @author Administrator
 *
 */
public class Test {

	public static void main(String[] args) {
		// 新建观察者
		Guancha g1 = new Guancha("打不死小强");
		Guancha g2 = new Guancha("没对象小明");

		// 新建被观察者 添加他的观察者
		BeiGuancha bgc = new BeiGuancha();
		bgc.addGuancha(g1);
		bgc.addGuancha(g2);

		// 修改被观察者状态
		bgc.setState("修改009");

		// 通知观察者 状态变了
		bgc.notifyAllGuancha();
	}

}


四、用事件委托实现观察者模式

我理解的所谓的事件委托实现 就是不让被观察者直接接触观察者(怕打架??)
而是通过一个中间人(Event) 如果被观察者需要通知观察者的话 就告诉Event 然后Event在去通知观察者 这里会用到反射

为什么会用到反射呢 Event存储了观察者对象 和 方法名 到使用的时候 是动态调用的~~

package com;

/**
 * 观察者
 * 
 * @author Administrator
 *
 */
public class Guancha {
	public Guancha(String name) {
		this.name = name;
	}

	private String name;

	/**
	 * 这是一个被调用的方法 当被观察者状态变化之后 就会调用所有他的观察者的这个方法
	 */
	public void update(String str) {
		System.out.println(name + ":收到被观察者的通知!   " + "被观察者状态:" + str);
	}
}

package com;

import java.lang.reflect.Method;
/**
 * Event 他就是把观察者跟被观察者隔离了  也就相当于是代理
 * @author Administrator
 *
 */
public class Event {
	// 观察者
	private Object object;
	// 方法名
	private String methodName;
	// 方法参数 我觉得 这个应该是在被观察者调用的时候才设置值的(也就是说Event的invoke方法传进来的参数)
	private Object[] params;
	// 方法参数类型
	private Class[] paramTypes;

	public Event(Object object, String methodName, Class... paramTypes) {
		this.object = object;
		this.methodName = methodName;
		this.paramTypes = paramTypes;
	}

	/*
	 * 执行该对象的该方法
	 */
	public void invoke(Object... args) {
		try {
			// 设置参数
			this.params = args;
			Method method = object.getClass().getMethod(methodName, paramTypes);
			if (null == method) {
				return;
			}
			method.invoke(object, params);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}

package com;

import java.util.ArrayList;
import java.util.List;

/**
 * 被观察者
 * 
 * @author Administrator
 *
 */
public class BeiGuancha {
	// 被观察者的状态
	private String state;

	// 存储他所有的观察者
	List<Event> events;

	public BeiGuancha() {
		events = new ArrayList<Event>();
	}

	// 添加观察者
	public void addGuancha(Event g) {
		events.add(g);
	}

	// 通知所有观察者
	public void notifyAllGuancha() {
		for (Event e : events) {
			e.invoke(state);
		}
	}

	public String getState() {
		return state;
	}

	public void setState(String state) {
		this.state = state;
	}

}

package com;

/**
 * 测试
 * 
 * @author Administrator
 *
 */
public class Test {

	public static void main(String[] args) {
		// 新建观察者
		Guancha g1 = new Guancha("打不死小强");
		Guancha g2 = new Guancha("没对象小明");

		// 新建被观察者 添加他的观察者
		BeiGuancha bgc = new BeiGuancha();
		bgc.addGuancha(new Event(g1, "update", new Class[]{String.class}));
		bgc.addGuancha(new Event(g2, "update", new Class[]{String.class}));

		// 修改被观察者状态
		bgc.setState("修改009");

		// 通知观察者 状态变了
		bgc.notifyAllGuancha();
	}

}
发布了431 篇原创文章 · 获赞 91 · 访问量 25万+

猜你喜欢

转载自blog.csdn.net/qq_36291682/article/details/89418988
今日推荐