概念
观察者模式:定义了对象之间的一对多依赖,这样一来,当一个对象状态改变时,他的所有依赖者都会收到通知并自动更新。
观察者模式涉及的角色
主题(Subject):一对多中的一,持有数据,当数据更新时,通知已注册的观察者
观察者(Observer):一对多中的多,接收主题数据做出响应
举个栗子
一位妈妈(主题)有两个孩子,取名为小爱和小冰(观察者)。一天小爱和小冰都去找她们的朋友玩,当到了吃饭的时间,妈妈总会打电话通知她们回来吃饭(孩子默认在妈妈那注册为观察者registerObserver),但中途小冰打电话和妈妈说:“不回来吃饭了,和朋友吃”(取消观察者这角色removeObserver)。所以最后,只有小冰收到妈妈的通知,并告诉她今天买了你喜欢吃的鸡腿(notifyObserver)。
代码
Person.java,Mother和Child都继承这个类[这步和讲述观察者模式没什么关系]
public class Person {
private String name;
public Person(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
Mother.java
public class Mother extends Person implements Subject{
/**
* 她要通知的孩子
*/
private ArrayList<Observer> children = new ArrayList<>();
/**
* 通知的内容
*/
private String message;
public Mother(String name) {
super(name);
}
@Override
public void registerObserver(Observer observer) {
children.add(observer);
}
@Override
public void removeObserver(Observer observer) {
children.remove(observer);
}
@Override
public void notifyObserver() {
children.forEach(observer -> observer.message(message));
}
public void sendMessage(String message) {
this.message = message;
// 通知她们
notifyObserver();
}
}
Child.java
public class Child extends Person implements Observer{
public Child(String name) {
super(name);
}
@Override
public void message(String m) {
System.out.println(getName() + "收到的消息:" + m);
}
}
Main.java
public class Main {
public static void main(String[] args) {
Mother mother = new Mother("妈妈");
Child xiaoBing = new Child("小冰");
Child xiaoAi = new Child("小爱");
// 孩子都是亲生的,吃饭时叫她们
mother.registerObserver(xiaoBing);
mother.registerObserver(xiaoAi);
mother.sendMessage("饭煮好了,回来吃饭,买了你们想吃的鸡腿");
System.out.println("------------------分割线-----------------------");
// 小爱说不回来吃了,取消通知她
mother.removeObserver(xiaoAi);
mother.sendMessage("饭煮好了,回来吃饭,买了你们想吃的鸡腿");
}
}
运行结果:
小冰收到的消息:饭煮好了,回来吃饭,买了你们想吃的鸡腿
小爱收到的消息:饭煮好了,回来吃饭,买了你们想吃的鸡腿
------------------分割线-----------------------
小冰收到的消息:饭煮好了,回来吃饭,买了你们想吃的鸡腿
优点
主题与观察者之间松耦合。有新类型的观察者出现时,主题的代码不需要修改。假如我们有一个新的具体类需要当观察者,我们不需要为了兼容新类型而修改主题的代码,所有要做的就是在新的类里实现此观察者接口,然后注册成观察者即可。
就好比如上面例子,如果国家不久的将来开放三胎政策,妈妈又生了个小娜,妈妈不需要修改自身的逻辑。如果孩子要回家吃饭就实现Observer接口,妈妈那registerObserver就OK。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。