Skip to content

Commit

Permalink
观察者模式
Browse files Browse the repository at this point in the history
  • Loading branch information
Q10Viking committed Mar 27, 2024
1 parent 1e64e18 commit ab1ef1d
Show file tree
Hide file tree
Showing 2 changed files with 121 additions and 2 deletions.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
123 changes: 121 additions & 2 deletions docs/designpattern/12 观察者模式.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,9 @@ typora-root-url: ..\.vuepress\public

## 基本模型

### 基本模型2
### 基本模型1

[Source Code](https://gitee.com/q10viking/design-patterns/tree/master/springboot-design-patterns/src/main/java/org/hzz/%E8%A1%8C%E4%B8%BA%E6%80%A7%E6%A8%A1%E5%BC%8F/BP1_%E8%A7%82%E5%AF%9F%E8%80%85%E6%A8%A1%E5%BC%8F/%E5%9F%BA%E6%9C%AC%E6%A8%A1%E5%9E%8B)

![image-20240327154307815](/images/designpattern/image-20240327154307815.png)

Expand All @@ -43,6 +45,110 @@ typora-root-url: ..\.vuepress\public
- ConcreteSubject(具体目标):具体目标是目标类的子类,通常包含有经常发生改变的数据。当它的状态发生改变时,向其各个观察者发出通知。同时它还实现了在目标类中定义的抽象业务逻辑方法(如果有)。如果无须扩展目标类,则具体目标类可以省略
- ConcreteObserver(具体观察者):在具体观察者中维护一个指向具体目标对象的引用,它存储具体观察者的有关状态,这些状态需要和具体目标的状态保持一致。它实现了在抽象观察者Observer中声明的update()方法。通常在实现时,可以调用具体目标类的attach()方法将自己添加到目标类的集合中或通过detach()方法将自己从目标类的集合中删除。

#### subject

```java
/**
* 目标主题抽象类
*/
public abstract class Subject {
// 定义一个观察者集合用于存储所有观察者对象
protected List<Observer> observers = new ArrayList();

// 注册方法,用于向观察者集合中添加一个观察者
public void attach(Observer observer){
observers.add(observer);
}

// 注销方法,用于在观察者集合中删除指定的观察者
public void detach(Observer observer){
observers.remove(observer);
}

// 声明抽象通知方法
public abstract void notifyAllObserver();
}
```

```java
package org.hzz.行为性模式.BP1_观察者模式.基本模型.impl;

import org.hzz.行为性模式.BP1_观察者模式.基本模型.Observer;
import org.hzz.行为性模式.BP1_观察者模式.基本模型.Subject;


import java.util.concurrent.Executors;
import java.util.concurrent.ThreadPoolExecutor;

public class ConcreteSubject extends Subject {
ThreadPoolExecutor executor = (ThreadPoolExecutor) Executors.newCachedThreadPool();
// 实现通知方法
@Override
public void notifyAllObserver() {
// 遍历观察者集合,调用每一个观察者的像一个响应方法
for (Observer observer: this.observers){
executor.submit(()-> observer.update());
}
}

public void doSomething(){
System.out.println("业务变动,通知各个观察者");
this.notifyAllObserver();
}
}

```



#### observer

```java
public interface Observer {
// 响应声明方法
public void update();
}

```

```java
public class ConcreteObserver implements Observer {
private String name;
public ConcreteObserver(String name){
this.name = name;
}
// 实现响应方法
@Override
public void update() {
// 具体响应代码
System.out.println(this.name+"收到通知");
}
}
```



#### 测试

```java
public class Test {
public static void main(String[] args) {
Subject subject = new ConcreteSubject();
subject.attach(new ConcreteObserver("broker-1"));
subject.attach(new ConcreteObserver("broker-2"));
subject.attach(new ConcreteObserver("broker-3"));

((ConcreteSubject)subject).doSomething();
}
}
/**
* 业务变动,通知各个观察者
* broker-2收到通知
* broker-3收到通知
* broker-1收到通知
*/
```



### 基本模型2
Expand Down Expand Up @@ -142,10 +248,23 @@ public class TestMain {



## 5. 源码应用
## 源码应用

```java
Spring:
org.springframework.context.ApplicationListener
```



## 案例

### 多人联机对战游戏

联盟成员受到攻击→发送通知给盟友→盟友做出响应。

![image-20240327153550482](/images/designpattern/image-20240327153550482.png)

![image-20240327170525513](/images/designpattern/image-20240327170525513.png)

AllyControlCenter充当目标类,ConcreteAllyControlCenter充当具体目标类,Observer充当抽象观察者,Player充当具体观察者

0 comments on commit ab1ef1d

Please sign in to comment.