3分钟看懂设计模式02:观察者模式-三、观察者模式2个代码实现案例
最编程
2024-02-24 08:08:14
...
通过2个案例,基本就可以知道观察者模式是怎么回事了,对照观察者模式的4个角色,敲一遍。
单纯熟悉4个角色的案例
先写一个被观察者Subject
public abstract class Subject {
// 存放观察者的集合
private Vector<Observer> obs = new Vector<>();
public void addObserver(Observer obs) {
this.obs.add(obs);
}
public void delObserver(Observer obs) {
this.obs.remove(obs);
}
// 通知方法,写成抽象方法让ConcreteSubject实现也一样的
protected void notifyObserver() {
for (Observer ob : obs) {
ob.update();
}
}
// 这里也是可写可不写,根据业务需求
public abstract void doSomething();
}
再写一个ConcreteSubject
public class ConcreteSubject extends Subject {
@Override
public void doSomething() {
System.out.println("被观察者事件发生改变");
this.notifyObserver();
}
}
观察者接口Observer
public interface Observer {
public void update();
}
观察者实现类ConcreteObserver,我们这里给出2个观察者
public class ConcreteObserver01 implements Observer {
@Override
public void update() {
System.out.println("观察者01收到状态变化信息,并进行处理...");
}
}
public class ConcreteObserver02 implements Observer {
@Override
public void update() {
System.out.println("观察者02收到状态变化信息,并进行处理...");
}
}
最后给出一个测试类,测试运行一个看看效果,看不明白代码就debug一下捋一捋。
以下代码的意思就是:
你得有东西被观察被监视吧?
所以先创建一个被观察者,比如我的账户余额。
你得设置哪些对象在观察、监视我的账户吧?
那就添加2个,我和我老婆。
然后就坐等账户余额有变化。
一旦发工资,状态变化!!!
dosomething()!
notifyObserver()!
遍历观察者列表!
update()!
这个时候我和我老婆分别对应各自实现的update()方法。
我马上去买了游戏。
我老婆马上去买了化妆品。
(不过这个例子好像不太合适,因为update方法里又会导致账户余额的变化,循环起来了,不过大概明白咋回事就行了。)
public class Client {
public static void main(String[] args) {
ConcreteSubject subject = new ConcreteSubject();
subject.addObserver(new ConcreteObserver01());
subject.addObserver(new ConcreteObserver02());
subject.doSomething();
}
}
盟友受攻击发通知,其他盟友做出响应
这个例子也是《设计模式的艺术》给出的案例。
我们的需求如下:
联盟成员收到攻击→发送通知给盟友→盟友做出响应。
如果按照上述思路设计,则每个成员必须持有其他所有成员的状态信息,导致系统开销过大。所以我们引入一个战队控制中心来统一维护所有战队成员信息。
依然是我们四步走:
先创建一个Subject被观察者,这里是AllyControlCenter控制中心
public abstract class AllyControlCenter {
/**
* 战队名称
*/
protected String allyName;
/**
* 定义一个集合,用来存储具体观察者,也就是战队成员
*/
protected Vector<Observer> players = new Vector<Observer>();
/**
* 加入战队
*/
public void join(Observer observer) {
System.out.println(observer.getName() + "加入" + this.allyName + "战队!");
players.add(observer);
}
/**
* 退出战队
*/
public void quit(Observer observer) {
System.out.println(observer.getName() + "退出" + this.allyName + "战队!");
players.remove(observer);
}
/**
* 声明抽象通知方法
* @param name
*/
public abstract void notifyObserver(String name);
/**
* 设置成员变量方法
* @param allyName
*/
public void setAllyName(String allyName) {
this.allyName = allyName;
}
/**
* 获取成员变量方法
* @return
*/
public String getAllyName() {
return this.allyName;
}
}
再创建一个ConcreteSubject具体被观察者ConcreteAllyControlCenter
public class ConcreteAllayControlCenter extends AllyControlCenter {
public ConcreteAllayControlCenter(String name) {
System.out.println(name + "战队组建成功!");
System.out.println("-------------");
this.allyName = name;
}
/**
* 实现通知方法
* @param name
*/
@Override
public void notifyObserver(String name) {
System.out.println(this.allyName + "战队紧急通知,盟友" + name + "遭受敌人攻击");
// 遍历观察者集合,调用每一个盟友(除了自己)的支援方法
for (Observer obs : players) {
if (!obs.getName().equalsIgnoreCase(name)) {
obs.help();
}
}
}
}
创建一个抽象观察者Observer
public interface Observer {
public String getName();
public void setName(String name);
/**
* 声明支援盟友的方法
*/
public void help();
/**
* 声明遭受攻击的方法
*/
public void beAttacked(AllyControlCenter acc);
}
在创建具体观察者Player
public class Player implements Observer {
private String name;
public Player(String name) {
this.name = name;
}
@Override
public String getName() {
return this.name;
}
@Override
public void setName(String name) {
this.name = name;
}
/**
* 支援盟友的方法实现
*/
@Override
public void help() {
System.out.println("坚持住,"+this.name +"来救你了!");
}
/**
* 遭受攻击的方法实现
* 当遭受攻击时,调用战队控制中心类的通知方法notifyObserver()来通知盟友
* @param acc
*/
@Override
public void beAttacked(AllyControlCenter acc) {
System.out.println(this.name + "被攻击!");
acc.notifyObserver(name);
}
}
测试运行
public class Client {
public static void main(String[] args) {
// 定义被观察者
AllyControlCenter acc = new ConcreteAllayControlCenter("金庸群侠");
// 定义4个观察者
Observer player1 = new Player("杨过");
Observer player2 = new Player("令狐冲");
Observer player3 = new Player("张无忌");
Observer player4 = new Player("段誉");
acc.join(player1);
acc.join(player2);
acc.join(player3);
acc.join(player4);
// 某成员遭受攻击
player1.beAttacked(acc);
}
}