设计模式(十六)——观察者模式

mac2026-02-05  0

上一篇:设计模式(十五)——中介者模式

下一篇:设计模式(十七)——备忘录模式

一、概述

官方解释:Define a one-to-many dependency between objects so that when one object changes state, all its dependents are notified and updated automatically.(定义对象间一种一对多的依赖关系,使得每当一个对象改变状态,则所有依赖于它的对象都会得到通知并被自动更新。)

我的理解:观察者模式的最简单的理解就是observer中带有两个方法,operate()和update(),并注入一个subject引用;subject中呆一个方法notify(),注入一个object的list引用,整个模式流程:

observer.operate() ==> subject.notify() ==> list中所有observer.update()

参与者:目标Subject(抽象目标AbstractSubject、具体目标ConcreteSubject),观察者Observer(抽象观察者AbstractObserver、具体观察者ConcreteObserver)

类图:

二、代码

代码1——单纯的观察者模式   代码2——观察者模式游戏例子  代码3——观察者模式游戏例子扩展

代码1——单纯的观察者模式:

package mypackage; import java.util.ArrayList; public class DesignPatternDemo { public static void main(String[] args) { Subject origin_Subject=new ConcreteSubject(); Observer observer1=new ConcreteObserver(); origin_Subject.attach(observer1); Observer observer2=new ConcreteObserver(); origin_Subject.attach(observer2); Observer observer3=new ConcreteObserver(); origin_Subject.attach(observer3); observer1.operate(origin_Subject);//客户端 observer.operate() --> origin_Subject._notify() --> list中所有obsever。update() } } abstract class Subject{ protected ArrayList<Observer> observers=new ArrayList<>(); public void attach(Observer observer){ observers.add(observer); } public void detach(Observer observer){ observers.remove(observer); } public abstract void _notify(); } class ConcreteSubject extends Subject{ @Override public void _notify() { for (Observer object:observers){ object.update(); } } } interface Observer{ public void update(); public void operate(Subject subject); } class ConcreteObserver implements Observer{ @Override public void update() { System.out.println("This ConcreteObserver update"); } @Override public void operate(Subject subject) { subject._notify(); } }

输出1:

This ConcreteObserver update This ConcreteObserver update This ConcreteObserver update

代码2——观察者模式游戏例子:

package mypackage; import java.util.ArrayList; public class DesignPatternDemo { public static void main(String[] args) { AllyControlCenter allyControlCenter=new ConcreteAllyControlCenter("AllyControlCenter"); Observer player1,player2,player3,player4; player1=new Player("player1"); allyControlCenter.join(player1); player2=new Player("player2"); allyControlCenter.join(player2); player3=new Player("player3"); allyControlCenter.join(player3); player4=new Player("player4"); allyControlCenter.join(player4); player1.beAttacked(allyControlCenter);//客户端 observer.beAttacked() --> allyControlCenter._notify() --> list中所有obsever。help() } } interface Observer{ public String getName(); public void setName(String name); public void help(); public void beAttacked(AllyControlCenter allyControlCenter); } class Player implements Observer{ private String name; public Player(String name){ this.name=name; } public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public void help() { System.out.println(this.name+" help"); } @Override public void beAttacked(AllyControlCenter allyControlCenter) { System.out.println(name+" beAttacked"); allyControlCenter.notifyObserver(name); } } abstract class AllyControlCenter{ protected String allyName; protected ArrayList<Observer> players=new ArrayList<>(); public String getAllyName() { return allyName; } public void setAllyName(String allyName) { this.allyName = allyName; } public AllyControlCenter(String allyName){ this.allyName=allyName; } public void join(Observer observer){ System.out.println(observer.getName()+" join in "+allyName); players.add(observer); } public void quit(Observer observer){ System.out.println(observer.getName()+" quit "+allyName); players.remove(observer); } public abstract void notifyObserver(String name); } class ConcreteAllyControlCenter extends AllyControlCenter{ public ConcreteAllyControlCenter(String allyName) { super(allyName); } @Override public void notifyObserver(String name) { System.out.println("This is ConcreteAllyControlCenter,notify all Observer"); for (Observer observer:players){ if (!observer.getName().equalsIgnoreCase(name)) { observer.help(); } } } }

输出2:

player1 join in AllyControlCenter player2 join in AllyControlCenter player3 join in AllyControlCenter player4 join in AllyControlCenter player1 beAttacked This is ConcreteAllyControlCenter,notify all Observer player2 help player3 help player4 help

代码3——观察者模式游戏例子扩展:

package mypackage; import java.util.ArrayList; public class DesignPatternDemo { public static void main(String[] args) { AllyControlCenter allyControlCenter=new ConcreteAllyControlCenter("AllyControlCenter"); Observer player1,player2,player3,player4; player1=new Player("player1"); allyControlCenter.join(player1); player2=new Player("player2"); allyControlCenter.join(player2); player3=new Player("player3"); allyControlCenter.join(player3); player4=new Player("player4"); allyControlCenter.join(player4); player1.beAttacked(allyControlCenter);//客户端 observer.beAttacked() --> allyControlCenter._notify() --> list中所有obsever。help() System.out.println("=======减少一个玩家========="); allyControlCenter.quit(player3); player1.beAttacked(allyControlCenter); } } interface Observer{ public String getName(); public void setName(String name); public void help(); public void beAttacked(AllyControlCenter allyControlCenter); } class Player implements Observer{ private String name; public Player(String name){ this.name=name; } public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public void help() { System.out.println(this.name+" help"); } @Override public void beAttacked(AllyControlCenter allyControlCenter) { System.out.println(name+" beAttacked"); allyControlCenter.notifyObserver(name); } } abstract class AllyControlCenter{ protected String allyName; protected ArrayList<Observer> players=new ArrayList<>(); public String getAllyName() { return allyName; } public void setAllyName(String allyName) { this.allyName = allyName; } public AllyControlCenter(String allyName){ this.allyName=allyName; } public void join(Observer observer){ System.out.println(observer.getName()+" join in "+allyName); players.add(observer); } public void quit(Observer observer){ System.out.println(observer.getName()+" quit "+allyName); players.remove(observer); } public abstract void notifyObserver(String name); } class ConcreteAllyControlCenter extends AllyControlCenter{ public ConcreteAllyControlCenter(String allyName) { super(allyName); } @Override public void notifyObserver(String name) { System.out.println("This is ConcreteAllyControlCenter,notify all Observer"); for (Observer observer:players){ if (!observer.getName().equalsIgnoreCase(name)) { observer.help(); } } } }

输出3:

player1 join in AllyControlCenter player2 join in AllyControlCenter player3 join in AllyControlCenter player4 join in AllyControlCenter player1 beAttacked This is ConcreteAllyControlCenter,notify all Observer player2 help player3 help player4 help =======减少一个玩家========= player3 quit AllyControlCenter player1 beAttacked This is ConcreteAllyControlCenter,notify all Observer player2 help player4 help

三、小结

观察者模式中,每个observer对象既是参与者,也是观察者,既可以被别的对象观察,也可以观察别的对象;subject提供一个observer的list存储和notify所有observer的方法。

注意:关于notify()中要不要通知operate()发起的那个observer,问题不大,根据项目开发需求来,可以通知,也可以不通知,毕竟一切为需求服务。

 

 

附:中介者模式和观察者模式区别

先写结论:在单纯的类图、模式结构上没有本质区别,区别是在项目开发中根据业务需求而造成的区别

明细:两种模式都是行为型设计模式,中介者模式核心类是Mediator,参与者类是Colleage类,观察者模式核心类是Subject,参与者类是Observer。

1、类图、类的结构组成相同:中介者模式  Mediator中注入Colleage类型的list,提供一个change()方法,Colleage类中注入Mediator引用,提供opearate()和update()方法

观察者模式 Subject注入Observer类型的list,提供一个notify()方法,Observer类中注入Subject引用,提供operate()和update()方法

从类图来看,注入包括类中属性注入和方法中形参注入,两种方式没有本质区别,只要可以完成业务逻辑即可,所以其类图类的结构没有本质区别

2、函数调用基本架构相同:中介者模式  colleage.operate() ==> mediator.change() ==> list中所有colleage.update()

观察者模式  observer.opearate() ==> subject.notify() ==> list中所有observer.update()

从函数调用基本架构来看,都是客户端直接调用参与者类的operate(),间接调用其他参与者类的update(),没有本质区别

3、业务逻辑意义不同:一般来说,中介者模式的各个参与类都是不同类对象,像另一文的Button Label ComboBox PictureBox,扩展的的时候要新建参与者类;而观察者类参与类是一个类的不同对象,像本文的Player类,扩展的时候不用新建参与类,只要在客户端新建一个对象就好了

4、业务逻辑——单向与双向不同:一般来说,中介者模式中,基本上都是双向的,每一个Colleage参与类都可以operate()间接调用其他Colleage参与类的update()方法,也可以被其他Colleage类的operate()间接调用,任何时候都是双向的,各个参与者之间是绝对平级的,没有任何上下级关系;

观察者模式中,可以是双向的(你可以观察我的变化,我也可以观察你的变化),也可以是单向的(我可以观察你的变化,你也可以观察我的变化,但是在业务逻辑上你观察我没有意义)(比如老师上课,老师与学生,老师Observer的变化通过Subject被学生Observer观察,但是学生的变化没有必要给老师观察;比如交警指挥,交警与司机,交警Observer的变化通过Subject被司机Observer观察,但是司机的变化没有必要给交警观察);

即:在观察者模式一些情况下,代码上完全可以实现双向观察,但逻辑上没有意义,从而造成了观察者模式中参与者Observer之间特殊与一般的关系.

5、侧重点不同:

观察者模式:不用关心这个列表里有谁,只用关心想让谁加入让谁退出;

中介者模式:用一个中介者对象来封装一系列的对象交互。中介者使得各对象不需要显式地相互引用,从而使其松散耦合,而且可以独立地改变它们之间的交互。

观察者模式一般提供join()和quit()方法,关心谁加入谁退出,中介者模式一般提供join()就好,也可以提供quit() 。

 

中介者模式:

https://blog.csdn.net/qq_36963950/article/details/102846157

观察者模式:

https://blog.csdn.net/qq_36963950/article/details/102866233

 

 

上一篇:设计模式(十五)——中介者模式

下一篇:设计模式(十七)——备忘录模式

最新回复(0)