观察者模式顾名思义,可以从名字本身看到最直接的一个身份,观察者,其次,有了观察者之后,考虑一下,观察者的本质就是去观察,观察谁呢?当然是被观察者。这听起来有些拗口。那就举几个列子,浅显易懂。
(1)上课时的学生和老师,学生观察老师授课的一举一动,老师将自身的知识传播个学生。 观察者:学生;被观察者:老师。
(2)对于近几年电商的流行,我想这个场景大家绝对见过,我注册了某个购物平台后,比如某宝,某东等等。平时时不时的会接收到一条短信,其内容大致是对于商品的描述以及优惠活动,可以让消费者知道我们平台有活动了,可以前来购买。这个时候,可以确定一下身份。 观察者:消费者 ;被观察者:某平台。
这里大家可能对第二个有点疑惑,消费者又没有像学生那样时刻关注老师的动向,这里消费者怎么会变成观察者呢?事实上,这里说道的观察并不是时时刻刻需要观察 被观察者,而是这2者间有一种约定,一旦有新的事情发生,被观察者会通知到观察者。还有一点,就是大家发现没?这里都是一对多的关系,一个老师对多个学生,一个平台对多个消费者。
就如图:
下面我们对第二个例子进行代码的实践
观察者抽象类
package com.pyj.myapplication.Subject;
/**
* 观察者抽象类
*
* @FileName: com.pyj.myapplication.Subject.Observer.java
* @date: 2017-08-01 11:49
*/
public abstract class Observer {
protected Subject subject;
public Observer(Subject subject) {
this.subject = subject;
regisiter();
}
//参数为Object ,便于扩展
abstract void update(Object obj);
//注册
void regisiter() {
if (subject != null) {
subject.addObserver(this);
System.out.println(getClass() + "注册");
}
}
//移除
void remove() {
if (subject != null) {
subject.removeObserver(this);
System.out.println(getClass() + "移除");
}
}
}
消费者1
package com.pyj.myapplication.Subject;
/**
* 消费者1
*
* @author: 流冥
* @date: 2017-08-01 12:03
*/
public class Customer1 extends Observer {
public Customer1(Subject subject) {
super(subject);
}
@Override
void update(Object obj) {
if (obj instanceof String) {
System.out.println(getClass()+"接收到内容: "+(String)obj);
} else if (obj instanceof Integer) {
System.out.println(getClass()+"接收到内容: "+((int)obj));
}
}
}
消费者2
package com.pyj.myapplication.Subject;
/**
* 消费者2
*
* @author: 流冥
* @date: 2017-08-01 12:03
*/
public class Customer2 extends Observer {
public Customer2(Subject subject) {
super(subject);
}
@Override
void update(Object obj) {
if (obj instanceof String) {
System.out.println(getClass()+"接收到内容: "+(String)obj);
} else if (obj instanceof Integer) {
System.out.println(getClass()+"接收到内容: "+((int)obj));
}
}
}
消费者3
package com.pyj.myapplication.Subject;
/**
* 消费者3
*
* @author: 流冥
* @date: 2017-08-01 12:03
*/
public class Customer3 extends Observer {
public Customer3(Subject subject) {
super(subject);
}
@Override
void update(Object obj) {
if (obj instanceof String) {
System.out.println(getClass() + "接收到内容: " + (String) obj);
} else if (obj instanceof Integer) {
System.out.println(getClass() + "接收到内容: " + ((int) obj));
}
}
}
被观察者类:Subject
package com.pyj.myapplication.Subject;
import java.util.ArrayList;
import java.util.List;
/**
* 被观察者
*
* @author: 流冥
* @date: 2017-08-01 11:56
*/
public class Subject {
List<Observer> list = new ArrayList<>();
//注册观察者
public void addObserver(Observer o) {
list.add(o);
}
//移除观察者
public void removeObserver(Observer o) {
list.remove(o);
}
//通知观察者信息
public void notiyAllObserver(Object o) {
for (Observer observer : list) {
observer.update(o);
}
}
}
接下来开始进行试验:
public class Test {
public static void main(String[] args){
//定义被观察者
Subject subject = new Subject();
//定义观察者并注册
Customer1 customer1 = new Customer1(subject);
Customer2 customer2 = new Customer2(subject);
Customer3 customer3 = new Customer3(subject);
}
}
首先进行创建和关系绑定,我们看下打印日志:
通过日志,我们可以看到观察者和被观察者已经绑定成功。
接下来进行被观察者的通知:
public class Test {
public static void main(String[] args){
//定义被观察者
Subject subject = new Subject();
//定义观察者并注册
Customer1 customer1 = new Customer1(subject);
Customer2 customer2 = new Customer2(subject);
Customer3 customer3 = new Customer3(subject);
subject.notiyAllObserver("亲,今天有新品上市了哦,打5折呢,速来抢购");
System.out.println("------------------------------------");
subject.notiyAllObserver(123456);
}
}
继续打印日志:
结果如上图,被观察者即消费者收到2条信息。这里要注意,我在代码中写到的这个方法
//参数为Object ,便于扩展
abstract void update(Object obj);
我的参数是Object类型的,这是便于扩展的一种写法,如果写死是String或者int的话,之后场景如果用到自定义的bean类的话进行通知,就会报错了。
接下来我们在进行解绑:
public class Test {
public static void main(String[] args){
//定义被观察者
Subject subject = new Subject();
//定义观察者并注册
Customer1 customer1 = new Customer1(subject);
Customer2 customer2 = new Customer2(subject);
Customer3 customer3 = new Customer3(subject);
subject.notiyAllObserver("亲,今天有新品上市了哦,打5折呢,速来抢购");
System.out.println("---------------------------------------------------------");
subject.notiyAllObserver(123456);
//解绑注册
customer1.remove();
subject.notiyAllObserver("亲,今天有新品上市了哦,打5折呢,速来抢购");
System.out.println("---------------------------------------------------------");
subject.notiyAllObserver(123456);
}
}
此处我们对Customer1进行了解绑 ,我们看下日志如何:
大家看到了吧 ,解绑了后,观察者继续发通知,Customer1就接收不到通知了。
到这里我讲的也到了尾声,对于举的列子我觉得还是比较容易理解的。若有读者看不懂或者我有写的不对的地方,也可以留言给我哦!