观察者模式(Observer Pattern)
观察者模式(Observer Pattern)也叫发布订阅模式(Publish/subscribe),它是一个在项目中经常 的模式,其定义如下: Define a one-to-many dependency between objects so that when one object changes state, all its dependents are notified and updated automatically. (定义对象间一种“一对多”的依赖关系,使得每当一个对象改变状态,则所有依赖于它的对象都会得到通知并被自动更新) 观察者的通用类图
Subject 被观察者 定义被观察者必须实现的职责,它必须能够动态地增加、取消观察者。它一般是抽象类或者是实现类,仅仅完成作为被观察者必须实现的职责:管理观察者并通知观察者。Observer观察者 观察者接收到消息后,即进行update(更新方法)操作,对接收到的信息进行处理。ConcreteSubject具体的被观察者 定义被观察者自己的业务,同时定义对哪些事件行通知。ConcreteObserver具体的观察者 每个观察者在接收到消息后的处理反应是不同的,各个观察者有自己的处理逻辑。
观察者模式的优点 1. 观察者和被观察者之间是抽象耦合 如何设计,则不 管是增加观察者还是被观察者都非常容易,而且在Java中都已经被盖同的层级的定义,在系统方面更是得心应手。 2. 建立一套触发机制 根据单一职责原则,每个类的职责是单一的,那么怎么把这个单一的串联成真实世界的复杂逻辑关系呢?比如我们去打猎,打死了一只母鹿,母鹿有三个幼崽,因后援会以了母鹿而饿死,继而……然后……这就是一个触发机制,形成了一个触发链。观察者模式可以完美实现这里的链条形式。
观察者模式的缺点 观察者模式需要考虑一下开发效率和运行效率量,一个空间站以者,多个观察者,开发和高度就会比较复杂,而且Java中消息的通知默认是顺序执行,一个观察者卡壳,会影响整体的执行效率。在这种情况下,一般考虑采用异步的方式。 多级触发时的效率更是让人担忧,大家在设计时注意考虑。
观察者模式的使用场景 1. 关联行为场景。需要注意的是,关联行为是可拆分的,而不是“组合”关系。 2. 事件多级触发场景。 3. 跨系统的消息交换场景,如消息队列的处理机制。
Subject类
package patterns.Observer.useUtil;
import java.util.Observable;
public class 信息暴露狂 extends Observable {
private int 道德 =
50;
private int 智商 =
50;
private int 体重 =
50;
public 信息暴露狂() {
System.out.println(
"我是暴露狂,我做什么事都要让别人知道!!!");
}
@Override
public String
toString() {
return "目前此人 道德"+道德+
" 智商"+智商+
" 体重"+体重;
}
public void 吃() {
System.out.println(
"我吃");
体重++;
setChanged();
this.notifyObservers(
"各种美拍高大上");
}
public void 喝() {
System.out.println(
"我喝");
体重++;
setChanged();
this.notifyObservers(
"各种美拍高大上");
}
public void 拉() {
System.out.println(
"我拉");
体重--;
setChanged();
this.notifyObservers(
"各种美拍高大上");
}
public void 撒() {
System.out.println(
"我撒");
体重--;
setChanged();
this.notifyObservers(
"各种美拍高大上");
}
public void 睡() {
System.out.println(
"我睡");
setChanged();
this.notifyObservers(
"各种美拍高大上");
}
public void 坑() {
System.out.println(
"我坑");
道德--;
setChanged();
this.notifyObservers(
"各种美拍高大上");
}
public void 蒙() {
System.out.println(
"我蒙");
智商--;
setChanged();
this.notifyObservers(
"各种美拍高大上");
}
public void 拐() {
System.out.println(
"我拐");
体重--;
道德--;
setChanged();
this.notifyObservers(
"各种美拍高大上");
}
public void 骗() {
System.out.println(
"我骗");
智商++;
道德--;
setChanged();
this.notifyObservers(
"各种美拍高大上");
}
public void 偷() {
System.out.println(
"我偷");
体重--;
道德--;
setChanged();
this.notifyObservers(
"各种美拍高大上");
}
public void 学习() {
System.out.println(
"我学习");
智商++;
道德++;
setChanged();
this.notifyObservers(
"各种美拍高大上");
}
public int get道德() {
return 道德;
}
public int get智商() {
return 智商;
}
public int get体重() {
return 体重;
}
}
Main
package patterns.Observer.useUtil;
import java.util.Observable;
import java.util.Observer;
public class Client {
public static void main(String[] args) {
Observer 朋友圈 =
new Observer() {
@Override
public void update(Observable o, Object arg) {
if(o
instanceof 信息暴露狂){
信息暴露狂 human = (信息暴露狂)o;
int 道德 =
10*human.get道德();
int 智商 =
10*human.get智商();
int 体重 =
10*human.get体重();
String after = arg+
"加道德"+道德+
"、加智商"+智商+
"、加体重"+体重+
"=====";
System.out.println(
"发到【朋友圈】:"+after+
" - "+o);
}
}
};
Observer 微博 =
new Observer() {
@Override
public void update(Observable o, Object arg) {
System.out.println(
"发到【微博】:"+arg+
" - "+o);
}
};
信息暴露狂 老陈头 =
new 信息暴露狂();
老陈头.addObserver(朋友圈);
老陈头.吃();
老陈头.喝();
老陈头.addObserver(微博);
老陈头.拉();
老陈头.撒();
老陈头.睡();
老陈头.坑();
老陈头.deleteObserver(朋友圈);
老陈头.蒙();
老陈头.拐();
老陈头.骗();
老陈头.偷();
老陈头.学习();
}
}
运行结果
我是暴露狂,我做什么事都要让别人知道!!! 我吃 发到【朋友圈】:各种美拍高大上加道德500、加智商500、加体重510===== - 目前此人 道德50 智商50 体重51 我喝 发到【朋友圈】:各种美拍高大上加道德500、加智商500、加体重520===== - 目前此人 道德50 智商50 体重52 我拉 发到【微博】:各种美拍高大上 - 目前此人 道德50 智商50 体重51 发到【朋友圈】:各种美拍高大上加道德500、加智商500、加体重510===== - 目前此人 道德50 智商50 体重51 我撒 发到【微博】:各种美拍高大上 - 目前此人 道德50 智商50 体重50 发到【朋友圈】:各种美拍高大上加道德500、加智商500、加体重500===== - 目前此人 道德50 智商50 体重50 我睡 发到【微博】:各种美拍高大上 - 目前此人 道德50 智商50 体重50 发到【朋友圈】:各种美拍高大上加道德500、加智商500、加体重500===== - 目前此人 道德50 智商50 体重50 我坑 发到【微博】:各种美拍高大上 - 目前此人 道德49 智商50 体重50 发到【朋友圈】:各种美拍高大上加道德490、加智商500、加体重500===== - 目前此人 道德49 智商50 体重50 我蒙 发到【微博】:各种美拍高大上 - 目前此人 道德49 智商49 体重50 我拐 发到【微博】:各种美拍高大上 - 目前此人 道德48 智商49 体重49 我骗 发到【微博】:各种美拍高大上 - 目前此人 道德47 智商50 体重49 我偷 发到【微博】:各种美拍高大上 - 目前此人 道德46 智商50 体重48 我学习 发到【微博】:各种美拍高大上 - 目前此人 道德47 智商51 体重48