目录
属于对象行为模式。
又叫 发布-订阅模式、模型-视图模式
多个对象间存在一对多的依赖关系,当一个对象状态发生改变时,其相关依赖对象皆得到通知,并被自动更新。
在观察者模式中参演的两个角色分别是观察者和被观察者。
主要优点:
1 降低了目标与观察者之间的耦合关系。两者之间是抽象耦合关系,符合依赖倒置原则。
2 目标与观察者之间建立了一套触发机制。
注意:
具体目标对象和具体观察者对象之间不能直接调用,否则将使两者之间紧密耦合起来,违反了面向对象的设计原则。
适用场景:
许多对象不是独立存在的,其中一个对象的行为改变可能会导致一个或者多个其他对象的行为也发生改变时。
比如我有两个孩子(两只猫),一个是哥哥,一个是妹妹,猫是会观察人类的表情来做出行为反应的。当观察到人类开心时,他就可以撒欢跑跳,当观察到人类的表情不开心时,他也会有所收敛。
这里的观察者就是两只猫,被观察者比如是他们的妈妈。一个妈妈的心情会导致多只猫不同的行为发生变化,这种情况,就可以使用观察者模式。
因为妈妈的表情会影响到孩子的行为,所以可以把妈妈的表情理解为一种通知。
观察者: 哥哥和妹妹 (多)
被观察者: 妈妈 (一)被观察者 通知 观察者
观察者 孩子(两只猫)
- package com.qing.observe;
-
- //观察者
- public abstract class Child {
- abstract void response(String mood);
- }
- package com.qing.observe;
-
- //观察者1
- public class Brother extends Child {
- @Override
- void response(String mood) {
- if("好心情".equals(mood)){
- System.out.println("哥哥 撒欢玩");
- }else{
- System.out.println("哥哥 乖乖地,不闹事");
- }
- }
- }
- package com.qing.observe;
-
- //观察者2
- public class Sister extends Child {
- @Override
- void response(String mood) {
- if("好心情".equals(mood)){
- System.out.println("妹妹 要抱抱");
- }else{
- System.out.println("妹妹 保持乖巧");
- }
- }
- }
被观察者 父母,里面有成员变量 孩子
- package com.qing.observe;
-
- import java.util.ArrayList;
- import java.util.List;
-
- //被观察者
- public abstract class Parent {
- List
children = new ArrayList(); -
- //添加观察者
- public void add(Child child){
- children.add(child);
- }
-
- //删除观察者
- public void remove(Child child){
- children.remove(child);
- }
-
-
- public abstract void showFace(String mood);
- }
妈妈的表情会通知孩子做出反应
- package com.qing.observe;
-
- //被观察者:妈妈
- public class Mother extends Parent {
-
- //做出反应
- @Override
- public void showFace(String mood) {
- for (Child child:children) {
- //根据妈妈脸上显示的心情,孩子做出反应
- child.response(mood);
- }
- }
- }
测试
- package com.qing.observe;
-
- public class Test1 {
- public static void main(String[] args) {
- Parent mother = new Mother();
- Child brother = new Brother();
- Child sister = new Sister();
- mother.add(brother);
- mother.add(sister);
- mother.showFace("好心情");
- System.out.println("---------------");
- mother.showFace("气炸了");
- }
- }
结果