feat: 重写观察者模式
This commit is contained in:
parent
fb7360c387
commit
b577e71956
Binary file not shown.
After Width: | Height: | Size: 27 KiB |
Binary file not shown.
After Width: | Height: | Size: 48 KiB |
Binary file not shown.
After Width: | Height: | Size: 23 KiB |
|
@ -0,0 +1,314 @@
|
||||||
|
# 设计模式
|
||||||
|
|
||||||
|
设计模式是对许多业务和算法的抽象,因此学习起来具有一定的难度。短时间内掌握是不可能的,需要通过不断的实践和理解来积累经验。对于已经在职场上工作,但后期才开始学习设计模式的人来说,可能会面临更多的挑战。
|
||||||
|
|
||||||
|
在学习设计模式时,很多概念趋于理论化,且种类繁多(设计模式总共有23种),如果没有进行系统的梳理,可能很难直接应用到实际场景中。
|
||||||
|
|
||||||
|
设计模式中的抽象类通常是接口或抽象类,这些类的实现会根据具体的业务需求进行调整,因而不一定是唯一的实现方式。
|
||||||
|
|
||||||
|
在我学习过程中,我试图将所学的内容总结下来,但由于篇幅有限,无法一一列举所有场景,只能举出一些常见的例子。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 策略模式
|
||||||
|
|
||||||
|
### 常见应用场景
|
||||||
|
|
||||||
|
策略模式广泛应用于支付、计算、文件压缩、登录等场景,尤其是在游戏中,如王者荣耀和PUBG的角色处理。值得注意的是,在实际开发中,一种业务场景可能会同时使用多种设计模式,因此,下面的介绍仅为简化并专注于策略模式的核心概念。
|
||||||
|
|
||||||
|
### 策略模式基础介绍
|
||||||
|
|
||||||
|
策略模式涉及三个主要角色:
|
||||||
|
1. **抽象策略(Strategy)**
|
||||||
|
2. **具体策略(Concrete Strategy)**
|
||||||
|
3. **上下文(Context)**
|
||||||
|
|
||||||
|
其中,`Context` 的概念较为抽象,通常用来持有策略并在运行时动态地切换策略。
|
||||||
|
|
||||||
|
![策略模式结构图](./images/设计模式-v2/image-20250201164040235.png)
|
||||||
|
|
||||||
|
#### 代码实现
|
||||||
|
|
||||||
|
策略模式的实现并不复杂,主要是定义三个角色:抽象策略、具体策略和上下文。为了更清晰地展示,我定义了两个具体策略,每个策略执行不同的操作。然后将策略放入上下文中,最终通过上下文来执行具体策略的方法。
|
||||||
|
|
||||||
|
```java
|
||||||
|
public class BaseStrategy {
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
// 创建具体策略
|
||||||
|
ConcreteStrategy1 concreteStrategy1 = new ConcreteStrategy1();
|
||||||
|
ConcreteStrategy2 concreteStrategy2 = new ConcreteStrategy2();
|
||||||
|
|
||||||
|
// 通过上下文执行策略
|
||||||
|
new Context(concreteStrategy1).doIt();
|
||||||
|
new Context(concreteStrategy2).doIt();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 抽象策略接口
|
||||||
|
public interface Strategy {
|
||||||
|
/**
|
||||||
|
* 执行策略方法
|
||||||
|
*/
|
||||||
|
void method();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 具体策略实现1
|
||||||
|
public static class ConcreteStrategy1 implements Strategy {
|
||||||
|
@Override
|
||||||
|
public void method() {
|
||||||
|
System.out.println("执行具体策略1...");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 具体策略实现2
|
||||||
|
public static class ConcreteStrategy2 implements Strategy {
|
||||||
|
@Override
|
||||||
|
public void method() {
|
||||||
|
System.out.println("执行具体策略2...");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 上下文类,持有策略并执行
|
||||||
|
public static class Context {
|
||||||
|
private final Strategy strategy;
|
||||||
|
|
||||||
|
public Context(Strategy strategy) {
|
||||||
|
this.strategy = strategy;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 执行策略的方法
|
||||||
|
*/
|
||||||
|
public void doIt() {
|
||||||
|
strategy.method();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 执行结果:
|
||||||
|
|
||||||
|
```java
|
||||||
|
执行具体策略1...
|
||||||
|
执行具体策略2...
|
||||||
|
```
|
||||||
|
|
||||||
|
### 示例-游戏角色
|
||||||
|
|
||||||
|
需要制作的游戏角色业务需求,基础角色是其他角色的抽象,包括国王、王后、骑士、士兵等,武器是一个接口所有武器都实现这个接口,切换武器(武器有主武器和副武器)可以调用`setPrimaryWeapon`和`setSubWeapon`。
|
||||||
|
|
||||||
|
![image-20250201173433406](./images/设计模式-v2/image-20250201173433406.png)
|
||||||
|
|
||||||
|
#### 代码实现
|
||||||
|
|
||||||
|
```java
|
||||||
|
public class GameCharacter {
|
||||||
|
public static void main(String[] args) {
|
||||||
|
Character soldier = new Soldier();
|
||||||
|
soldier.fight();
|
||||||
|
|
||||||
|
Character king = new King();
|
||||||
|
king.setPrimaryWeapon(new AxeWeapon());
|
||||||
|
king.fight();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 武器接口
|
||||||
|
interface Weapon {
|
||||||
|
String function();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 各种武器实现
|
||||||
|
public static class SwordWeapon implements Weapon {
|
||||||
|
@Override
|
||||||
|
public String function() {
|
||||||
|
return "⚔️ ⚔️ ⚔️";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class AxeWeapon implements Weapon {
|
||||||
|
@Override
|
||||||
|
public String function() {
|
||||||
|
return "🪓 🪓 🪓";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class KnifeWeapon implements Weapon {
|
||||||
|
@Override
|
||||||
|
public String function() {
|
||||||
|
return "🔪 🔪 🔪";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 抽象角色类
|
||||||
|
public abstract static class Character {
|
||||||
|
String name;
|
||||||
|
@Setter
|
||||||
|
private Weapon primaryWeapon;
|
||||||
|
@Setter
|
||||||
|
private Weapon subWeapon;
|
||||||
|
|
||||||
|
public Character(String name) {
|
||||||
|
this.name = name;
|
||||||
|
// 默认武器配置
|
||||||
|
this.primaryWeapon = new SwordWeapon();
|
||||||
|
this.subWeapon = new KnifeWeapon();
|
||||||
|
}
|
||||||
|
|
||||||
|
void fight() {
|
||||||
|
if (primaryWeapon != null && subWeapon != null) {
|
||||||
|
String primary = primaryWeapon.function();
|
||||||
|
String sub = subWeapon.function();
|
||||||
|
System.out.println(name + ":" + primary + "和" + sub);
|
||||||
|
} else {
|
||||||
|
System.out.println(name + "没有武器!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 国王角色
|
||||||
|
public static class King extends Character {
|
||||||
|
public King() {
|
||||||
|
super("King");
|
||||||
|
setPrimaryWeapon(new SwordWeapon());
|
||||||
|
setSubWeapon(new KnifeWeapon());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 士兵角色
|
||||||
|
public static class Soldier extends Character {
|
||||||
|
public Soldier() {
|
||||||
|
super("Soldier");
|
||||||
|
setPrimaryWeapon(new AxeWeapon());
|
||||||
|
setSubWeapon(new SwordWeapon());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 运行结果:
|
||||||
|
|
||||||
|
```java
|
||||||
|
Soldier:🪓 🪓 🪓和⚔️ ⚔️ ⚔️
|
||||||
|
King:🪓 🪓 🪓和🔪 🔪 🔪
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 观察者模式
|
||||||
|
|
||||||
|
观察者有四个角色,观察者(Observe)和具体观察者(Concrete Observe)、主题(Subject)和具体主题(Concrete Subject),具体观察者和具体主题可以多个。
|
||||||
|
|
||||||
|
![image-20250201175728138](./images/设计模式-v2/image-20250201175728138.png)
|
||||||
|
|
||||||
|
### 简单示例
|
||||||
|
|
||||||
|
其中主题中有3个方法,添加(或者理解成注册都可以)、移出、通知,差不多都是这三个方法,其中添加可以理解成注册加入总之是往数组中添加观察者。
|
||||||
|
|
||||||
|
#### 代码实现
|
||||||
|
|
||||||
|
```java
|
||||||
|
public class ObserverDemo {
|
||||||
|
public static void main(String[] args) {
|
||||||
|
// 定义的主题
|
||||||
|
News news = new News();
|
||||||
|
|
||||||
|
// 观察者
|
||||||
|
SisterObserver sisterObserver = new SisterObserver();
|
||||||
|
GirlfriendObserver girlfriendObserver = new GirlfriendObserver();
|
||||||
|
|
||||||
|
// 添加观察者
|
||||||
|
news.addObserver(sisterObserver);
|
||||||
|
news.notifyObservers("添加了妹妹");
|
||||||
|
|
||||||
|
System.out.println("\n-----------------分割线-----------------\n");
|
||||||
|
|
||||||
|
// 添加女朋友
|
||||||
|
news.addObserver(girlfriendObserver);
|
||||||
|
news.notifyObservers("添加了女朋友");
|
||||||
|
|
||||||
|
System.out.println("\n-----------------分割线-----------------\n");
|
||||||
|
news.removeObserver(girlfriendObserver);
|
||||||
|
news.notifyObservers("需要和妹妹说点悄悄话,将女朋友移除了,这时女朋友听不见我们说话。。。");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 观察者接口
|
||||||
|
@FunctionalInterface
|
||||||
|
interface Observer {
|
||||||
|
void update(String message);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 主题接口
|
||||||
|
interface Subject {
|
||||||
|
void addObserver(Observer observer);
|
||||||
|
|
||||||
|
void removeObserver(Observer observer);
|
||||||
|
|
||||||
|
void notifyObservers(String message);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 妹妹观察者
|
||||||
|
static class SisterObserver implements Observer {
|
||||||
|
@Override
|
||||||
|
public void update(String message) {
|
||||||
|
System.out.println("SisterObserver 接受到消息:" + message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 女朋友观察者
|
||||||
|
static class GirlfriendObserver implements Observer {
|
||||||
|
@Override
|
||||||
|
public void update(String message) {
|
||||||
|
System.out.println("GirlfriendObserver 接受到消息:" + message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 主题类
|
||||||
|
static class News implements Subject {
|
||||||
|
|
||||||
|
private final List<Observer> observerList = new ArrayList<>();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addObserver(Observer observer) {
|
||||||
|
observerList.add(observer);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void removeObserver(Observer observer) {
|
||||||
|
observerList.remove(observer);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void notifyObservers(String message) {
|
||||||
|
for (Observer observer : observerList) {
|
||||||
|
observer.update(message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 运行结果:
|
||||||
|
|
||||||
|
```java
|
||||||
|
SisterObserver 接受到消息:添加了妹妹
|
||||||
|
|
||||||
|
-----------------分割线-----------------
|
||||||
|
|
||||||
|
SisterObserver 接受到消息:添加了女朋友
|
||||||
|
GirlfriendObserver 接受到消息:添加了女朋友
|
||||||
|
|
||||||
|
-----------------分割线-----------------
|
||||||
|
|
||||||
|
SisterObserver 接受到消息:需要和妹妹说点悄悄话,将女朋友移除了,这时女朋友听不见我们说话。。。
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 装饰者模式
|
||||||
|
|
||||||
|
一共有四个角色。
|
||||||
|
|
||||||
|
- 抽象组件:一般是最原始、最基础的对象。
|
||||||
|
- 具体组件:一般是最原始最基础的实现对象,可以有多个(只是数量不多),可以大致看下`InputStream`UML结构图。
|
||||||
|
- 装饰角色:继承或者实现**抽象组件**这是最关键的地方。
|
||||||
|
- 具体装饰角色:可以有多个实现或者继承**装饰角色**。
|
|
@ -374,8 +374,6 @@ public class Client {
|
||||||
- **工厂方法模式**:通过子类来决定产品的创建,适合产品种类较多时,且产品可能会变化。
|
- **工厂方法模式**:通过子类来决定产品的创建,适合产品种类较多时,且产品可能会变化。
|
||||||
- **抽象工厂模式**:提供多个相关的产品的创建接口,适合需要创建一系列相关产品的场景。
|
- **抽象工厂模式**:提供多个相关的产品的创建接口,适合需要创建一系列相关产品的场景。
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## 观察者模式
|
## 观察者模式
|
||||||
|
|
||||||
观察者模式是一种行为设计模式,它允许一个对象(被观察者)在其状态发生变化时,自动通知所有依赖于它的对象(观察者),而不需要知道这些观察者的具体细节。其主要思想是实现“低耦合”,即对象之间的关系通过接口进行松散连接。为了避免使用过时的类,我们可以手动实现观察者模式。我们需要定义一个“观察者”接口和一个“被观察者”接口,并在被观察者中维护一个观察者的列表,通知观察者更新状态。
|
观察者模式是一种行为设计模式,它允许一个对象(被观察者)在其状态发生变化时,自动通知所有依赖于它的对象(观察者),而不需要知道这些观察者的具体细节。其主要思想是实现“低耦合”,即对象之间的关系通过接口进行松散连接。为了避免使用过时的类,我们可以手动实现观察者模式。我们需要定义一个“观察者”接口和一个“被观察者”接口,并在被观察者中维护一个观察者的列表,通知观察者更新状态。
|
||||||
|
@ -483,7 +481,7 @@ public interface Subject {
|
||||||
#### 主体实现
|
#### 主体实现
|
||||||
|
|
||||||
```java
|
```java
|
||||||
import cn.bunny.pattern3.observer.Observer;
|
import cn.bunny.pattern3.demo1.observer.Observer;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
@ -526,11 +524,11 @@ public class WeatherStationSubject implements Subject {
|
||||||
### 运行
|
### 运行
|
||||||
|
|
||||||
```java
|
```java
|
||||||
import cn.bunny.pattern3.observer.Observer;
|
import cn.bunny.pattern3.demo1.observer.Observer;
|
||||||
import cn.bunny.pattern3.observer.Observer1;
|
import cn.bunny.pattern3.demo1.observer.Observer1;
|
||||||
import cn.bunny.pattern3.observer.Observer2;
|
import cn.bunny.pattern3.demo1.observer.Observer2;
|
||||||
import cn.bunny.pattern3.observer.Observer3;
|
import cn.bunny.pattern3.demo1.observer.Observer3;
|
||||||
import cn.bunny.pattern3.subject.WeatherStationSubject;
|
import cn.bunny.pattern3.demo1.subject.WeatherStationSubject;
|
||||||
|
|
||||||
public class Main {
|
public class Main {
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
|
@ -662,17 +660,17 @@ public class FilterCameraDecorator extends CameraDecorator {
|
||||||
public class Main {
|
public class Main {
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
System.out.println("------------------执行简单的拍照-------------------");
|
System.out.println("------------------执行简单的拍照-------------------");
|
||||||
|
|
||||||
TakePhotoCamera takePhotoCamera = new TakePhotoCamera();
|
TakePhotoCamera takePhotoCamera = new TakePhotoCamera();
|
||||||
takePhotoCamera.operation();
|
takePhotoCamera.operation();
|
||||||
|
|
||||||
System.out.println("-------------------需要美颜功能------------------");
|
System.out.println("-------------------需要美颜功能------------------");
|
||||||
|
|
||||||
BeautyCameraDecorator beautyCameraDecorator = new BeautyCameraDecorator(takePhotoCamera);
|
BeautyCameraDecorator beautyCameraDecorator = new BeautyCameraDecorator(takePhotoCamera);
|
||||||
beautyCameraDecorator.operation();
|
beautyCameraDecorator.operation();
|
||||||
|
|
||||||
System.out.println("-------------------需要美颜功能之后滤镜------------------");
|
System.out.println("-------------------需要美颜功能之后滤镜------------------");
|
||||||
|
|
||||||
FilterCameraDecorator filterCameraDecorator = new FilterCameraDecorator(beautyCameraDecorator);
|
FilterCameraDecorator filterCameraDecorator = new FilterCameraDecorator(beautyCameraDecorator);
|
||||||
filterCameraDecorator.operation();
|
filterCameraDecorator.operation();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
package cn.bunny.pattern3;
|
package cn.bunny.pattern3.demo1;
|
||||||
|
|
||||||
|
|
||||||
import cn.bunny.pattern3.observer.Observer;
|
import cn.bunny.pattern3.demo1.observer.Observer;
|
||||||
import cn.bunny.pattern3.observer.Observer1;
|
import cn.bunny.pattern3.demo1.observer.Observer1;
|
||||||
import cn.bunny.pattern3.observer.Observer2;
|
import cn.bunny.pattern3.demo1.observer.Observer2;
|
||||||
import cn.bunny.pattern3.observer.Observer3;
|
import cn.bunny.pattern3.demo1.observer.Observer3;
|
||||||
import cn.bunny.pattern3.subject.WeatherStationSubject;
|
import cn.bunny.pattern3.demo1.subject.WeatherStationSubject;
|
||||||
|
|
||||||
public class Main {
|
public class Main {
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
|
@ -1,4 +1,4 @@
|
||||||
package cn.bunny.pattern3.observer;
|
package cn.bunny.pattern3.demo1.observer;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 观察者接口
|
* 观察者接口
|
|
@ -1,4 +1,4 @@
|
||||||
package cn.bunny.pattern3.observer;
|
package cn.bunny.pattern3.demo1.observer;
|
||||||
|
|
||||||
public class Observer1 implements Observer {
|
public class Observer1 implements Observer {
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
package cn.bunny.pattern3.observer;
|
package cn.bunny.pattern3.demo1.observer;
|
||||||
|
|
||||||
public class Observer2 implements Observer {
|
public class Observer2 implements Observer {
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
package cn.bunny.pattern3.observer;
|
package cn.bunny.pattern3.demo1.observer;
|
||||||
|
|
||||||
public class Observer3 implements Observer {
|
public class Observer3 implements Observer {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
package cn.bunny.pattern3.subject;
|
package cn.bunny.pattern3.demo1.subject;
|
||||||
|
|
||||||
import cn.bunny.pattern3.observer.Observer;
|
import cn.bunny.pattern3.demo1.observer.Observer;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 被观察者接口
|
* 被观察者接口
|
|
@ -1,7 +1,7 @@
|
||||||
package cn.bunny.pattern3.subject;
|
package cn.bunny.pattern3.demo1.subject;
|
||||||
|
|
||||||
|
|
||||||
import cn.bunny.pattern3.observer.Observer;
|
import cn.bunny.pattern3.demo1.observer.Observer;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
|
@ -0,0 +1,84 @@
|
||||||
|
package cn.bunny.pattern3.demo2;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class ObserverDemo {
|
||||||
|
public static void main(String[] args) {
|
||||||
|
// 定义的主题
|
||||||
|
News news = new News();
|
||||||
|
|
||||||
|
// 观察者
|
||||||
|
SisterObserver sisterObserver = new SisterObserver();
|
||||||
|
GirlfriendObserver girlfriendObserver = new GirlfriendObserver();
|
||||||
|
|
||||||
|
// 添加观察者
|
||||||
|
news.addObserver(sisterObserver);
|
||||||
|
news.notifyObservers("添加了妹妹");
|
||||||
|
|
||||||
|
System.out.println("\n-----------------分割线-----------------\n");
|
||||||
|
|
||||||
|
// 添加女朋友
|
||||||
|
news.addObserver(girlfriendObserver);
|
||||||
|
news.notifyObservers("添加了女朋友");
|
||||||
|
|
||||||
|
System.out.println("\n-----------------分割线-----------------\n");
|
||||||
|
news.removeObserver(girlfriendObserver);
|
||||||
|
news.notifyObservers("需要和妹妹说点悄悄话,将女朋友移除了,这时女朋友听不见我们说话。。。");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 观察者接口
|
||||||
|
@FunctionalInterface
|
||||||
|
interface Observer {
|
||||||
|
void update(String message);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 主题接口
|
||||||
|
interface Subject {
|
||||||
|
void addObserver(Observer observer);
|
||||||
|
|
||||||
|
void removeObserver(Observer observer);
|
||||||
|
|
||||||
|
void notifyObservers(String message);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 妹妹观察者
|
||||||
|
static class SisterObserver implements Observer {
|
||||||
|
@Override
|
||||||
|
public void update(String message) {
|
||||||
|
System.out.println("SisterObserver 接受到消息:" + message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 女朋友观察者
|
||||||
|
static class GirlfriendObserver implements Observer {
|
||||||
|
@Override
|
||||||
|
public void update(String message) {
|
||||||
|
System.out.println("GirlfriendObserver 接受到消息:" + message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 主题类
|
||||||
|
static class News implements Subject {
|
||||||
|
|
||||||
|
private final List<Observer> observerList = new ArrayList<>();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addObserver(Observer observer) {
|
||||||
|
observerList.add(observer);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void removeObserver(Observer observer) {
|
||||||
|
observerList.remove(observer);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void notifyObservers(String message) {
|
||||||
|
for (Observer observer : observerList) {
|
||||||
|
observer.update(message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue