在软件开发中,很多时候我们需要实现这么一个场景:
场景1:当对象A的状态变化了,对象B的状态也需要变化;
实现方式:年幼的我们会在得知对象A变化的代码里,添加对象B的变化方法
这是java最简单最浅显的实现方式;但是,现在甲方爸爸的需求变化了:
场景2:当对象A的状态变化了,对象B,对象C,对象D,对象E的状态也需要变化;
实现方式:按照简单的开发模式,我们会继续在对象A变化的代码里,添加BCDE对象的变化代码(这么一看,也可以实现甲方爸爸,需求)
然后,甲方爸爸开始得寸进尺了:
场景3:场景2的基础上又加了对象FGHIJK,而且A的状态分成三种,每种状态的变化,要求有对应的对象变化,状态1:BEF;状态2:CGH;状态3:..
无奈的你,又开始在对象A变化的代码里,开始增加状态的判断,增加对象变化的方法,然后你最后发现,一个A对象状态变化的代码塞满你整个屏幕,每一次甲方爸爸更新了需求,都需要把对象A的代码重新梳理一遍,忍无可忍的你,终于找隔壁的王师傅借了一套武功秘籍 - 观察者模式!
观察者模式中存在两个角色: 被观察者和观察者:每次被观察者发生变化时候,观察者能立马感知到;
在上面的场景里面,你发现可以很容易地使用观察者模式:
对象A就相当于被观察者,其他对象就相当于观察者;每次A变化时,其他对象能立马感知到;
其实我更喜欢把这个当做一种消息订阅来理解,对象A相当于微信,对象BCDE相当于用户,每个用户在微信上订阅了不同的工作号,当微信有消息时,会根据公众号的订阅者将消息发给对应的订阅用户。
借用《JAVA与模式》书里的话就是:
观察者模式是对象的行为模式,又叫发布-订阅(Publish/Subscribe)模式、模型-视图(Model/View)模式、源-监听器(Source/Listener)模式或从属者(Dependents)模式。
观察者模式的好处在于观察者的动作代码和被观察者的动作代码是低耦合的,不需要和上面场景的实现方式一样,代码都写在一块。
这样子我们就能明确代码的大致方向了:
1、编写观察者
2、编写被观察者
3、编写观察者如何订阅被观察者
观察不是一个对象,而是一类对象,所以我们要先有一个观察者的接口:
/** * @author:admin * @Version: 0.1 created by 2020/2/19 2:33 PM * 观察者接口 */ public interface Iwatch { public void acceptMessage(String message); }
然后通过这个接口产生对应的观察者:
/** * @author:admin * @Version: 0.1 created by 2020/2/19 2:37 PM */ public class WatchB implements Iwatch{ @Override public void acceptMessage(String message) { System.out.println("我是观察者B",收到的消息是:"+message
); } }
/** * @author:admin * @Version: 0.1 created by 2020/2/19 2:37 PM */ public class WatchC implements Iwatch{ @Override public void acceptMessage(String message) { System.out.println("我是观察者C,收到的消息是:"+message
); } }
/** * @author:admin * @Version: 0.1 created by 2020/2/19 2:37 PM */ public class WatchD implements Iwatch{ @Override public void acceptMessage(String message) { System.out.println("我是观察者D,收到的消息是:"+message
); } }
有了观察者之后呢,我们还需要有观察的对象--被观察者
被观察者,我将它命名为观察者管理员,他有着一个全局的小册子-watchCollections,这里面放着还需要进行观察任务的观察者
/**
* @author:admin
* @Version: 0.1 created by 2020/2/19 2:30 PM
*/
public class WatchManager {
public static Set<Iwatch> watchCollections = new LinkedHashSet<>();
/**
* 将观察者注册进来
* @param iwatch
*/
public synchronized void addWatch(Iwatch iwatch){
watchCollections.add(iwatch);
}
/**
* 将观察者移出
* @param iwatch
*/
public synchronized void deleteWatch(Iwatch iwatch) {
watchCollections.remove(iwatch);
}
/**
* 对观察者发起消息通知
* @param message
*/
public synchronized void sendMessage(String message){
for(Iwatch iwatch : watchCollections){
iwatch.acceptMessage(message);
}
}
}
/** * @author:admin * @Version: 0.1 created by 2020/2/19 2:54 PM */ public class demo { public static void main(String[] args) { WatchB watchB = new WatchB(); WatchD watchD = new WatchD(); WatchManager watchManager = new WatchManager(); //将观察者B和观察者D注册到观察者管理员的小手册里 watchManager.addWatch(watchB); watchManager.addWatch(watchD); // 观察者管理员发送信息 watchManager.sendMessage("我是观察者管理员,我更新消息了"); } }
执行之后就能在控制台看到,观察者的响应了:
原文:https://www.cnblogs.com/wcf1220/p/12331330.html