设计模式 - observer

简单来讲,就是observer依赖于subject,当subject发生变化时,observer得到通知,并将状态与subject同步,常来用于维护对象间状态的一致性。

 

 

observer的工作过程大体如下:

注册:

observer将自身注册到subject中,subject中通常保有一份注册的observer列表。

通知:

当subject发生变化时,会遍历自身保有的观察者列表,并调用observer的update方法,更新其自身状态

销毁:

当注销时,销毁subject中的observer即可。

缺陷:

a. 观察者模式中的observer并不知道对方的存在,因此在subject中状态改变后,难以预料对其他observer的影响。

b. 当删除subject中,需要注意去除observer中的悬挂引用。通常的解决方案是在删除subject时,通知observer进行处理。

改进:

观察者模式的核心是依赖关系,上面的例子中,observer和subject的关系尤其自身来保存,但当遇到复杂的依赖和注册关系,以及不同的通知机制时,可以通过抽象出changeManager来减少observer反应其变更的工足量。

如:如果一个操作涉及到几个相互依赖的目标进行改动,就必须保证在所有目标都已经更新完毕后,才一次性通知其observer,而非每个subject分别通知。

 

代码示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
package com.inspur.jiyq.designpattern.observer;
 
import com.inspur.jiyq.designpattern.observer.impl.ConcreteObserver;
import com.inspur.jiyq.designpattern.observer.impl.ConcreteSubject;
 
public class ObserverMain {
    public static void main(String[] args)
    {
        Subject subject = new ConcreteSubject();
         
        //observer注册到suject中
        ConcreteObserver observer1 = new ConcreteObserver(subject);
        ConcreteObserver observer2 = new ConcreteObserver(subject);
         
        subject.notice();
    }
}

  

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
package com.inspur.jiyq.designpattern.observer;
 
public interface Subject {
     
    /**
     * 注册observer
     */
    public void attach(Observer observer);
     
    /**
     * 注销 observer
     */
    public void detach(Observer observer);
     
    /**
     * 通知observer
     */
    public void notice();
     
    /**
     * 获取内部状态
     * @return
     *  内部状态
     */
    public String getState();
     
    /**
     * 设置内部状态
     *
     * @param innerState
     *          内部状态
     */
    public void setState(String innerState);
}

  

1
2
3
4
5
package com.inspur.jiyq.designpattern.observer;
 
public interface Observer {
    public void update(Subject subject);
}

  

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
package com.inspur.jiyq.designpattern.observer.impl;
 
import java.util.ArrayList;
import java.util.List;
 
import com.inspur.jiyq.designpattern.observer.Observer;
import com.inspur.jiyq.designpattern.observer.Subject;
 
public class ConcreteSubject implements Subject {
    private List<Observer> observers = new ArrayList<Observer>();
 
    private String innerState = null;
 
    @Override
    public void attach(Observer observer) {
        this.observers.add(observer);
    }
 
    @Override
    public void detach(Observer observer) {
        this.observers.remove(observer);
    }
 
    @Override
    public void notice() {
        for (Observer observer : observers) {
            // 将自身状态更新至observer,保证状态一致性
            observer.update(this);
        }
    }
 
    /**
     * 返回自身状态
     */
    @Override
    public String getState() {
        return innerState;
    }
 
    /**
     * 返回自身状态
     */
    public void setState(String innerState) {
        this.innerState = innerState;
    }
}

  

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
package com.inspur.jiyq.designpattern.observer.impl;
 
import com.inspur.jiyq.designpattern.observer.Observer;
import com.inspur.jiyq.designpattern.observer.Subject;
 
public class ConcreteObserver implements Observer {
    Subject subject;
     
    public ConcreteObserver(Subject subject)
    {
        this.subject= subject;
        subject.attach(this);;
    }
     
    @Override
    public void update(Subject subject) {
        System.out.println("I got a new state.");
    }
}

  

 

posted @   纪玉奇  阅读(423)  评论(0编辑  收藏  举报
编辑推荐:
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· .NET周刊【3月第1期 2025-03-02】
· [AI/GPT/综述] AI Agent的设计模式综述
点击右上角即可分享
微信分享提示