设计模式-----观察者模式(Obsever)

本文详细介绍了观察者模式的概念、组成部分及其实现方式,并通过示例代码展示了如何在Java中实现观察者模式。此外,还讨论了观察者模式的应用场景。

定义了对象之间的一对多依赖,这样一来,当一个对象状态改变时,他的所有依赖者都会收到通知并自动更新。


观察者模式的组成:


抽象主题角色:把所有对观察者对象的引用保存在一个集合中。抽象主题提供一个接口,可以增加和删除观察者角色。

具体主题角色:在具体主题内部状态改变时,给所有登记过的观察者发出通知。


抽象观察者角色为所有具体的观察者定义一个接口,在得到主题的通知时更新自己

具体观察者角色:该角色实现抽象观察者角色所要求的更新接口,以便使本身的状态与主题的状态相协调。


观察者模式UML图:


观察者模式示例代码:

主题接口类 Subject.java

public interface Subject {
	public void addObserver(Observer observer);

	public void removeObserver(Observer observer);

	public void notifyObservers(String str);
}

具体主题类(可以实现多个) ConcreteSubject.java

import java.util.ArrayList;

public class ConcreteSubject implements Subject {
	ArrayList<Observer> observers = new ArrayList<Observer>();

	public void addObserver(Observer observer) {
		observers.add(observer);
	}

	public void removeObserver(Observer observer) {
		observers.remove(observer);
	}

	@Override
	public void notifyObservers(String str) {
		//通知所有观察者
		for (Observer o : observers) {
			o.update(str);
		}
	}
}


观察者接口类 Observer.java

public interface Observer {
	public void update(String str);
}


具体观察者类(可以实现多个)ConcreteObserver.java

public class ConcreteObserver implements Observer {

	@Override
	public void update(String str) {
		System.out.println("通知了observer--》 " + str);
	}
}

测试类 Test.java

/**
 * 测试观察者模式
 * 
 * @author neng
 * 
 */
public class Test {

	public static void main(String[] args) {
		// 只要是实现接口的观察者与主题即可. 多对多
		ConcreteObserver observer1 = new ConcreteObserver();
		ConcreteObserver observer2 = new ConcreteObserver();

		ConcreteSubject concreteSubject1 = new ConcreteSubject();

		concreteSubject1.addObserver(observer1);
		concreteSubject1.addObserver(observer2);
		concreteSubject1.notifyObservers("这个是消息!!!!");

		concreteSubject1.removeObserver(observer2);
		concreteSubject1.notifyObservers("命令!!");
	}

}

观察者模式用途:

Android,ios中的Notification即用观察者模式实现。
Java中的事件监听也用观察者模式实现。

多个对象(一对多,多对多)之间通讯可以用观察者模式,主题和观察者之间的耦合度非常低,可拓展性很强!


转载请注明出处:http://blog.youkuaiyun.com/xn4545945  



<think>我们正在讨论Vue.js中的响应式系统。`__ob__`属性是Vue内部用于实现响应式的一个对象,它是Observer类的实例。当我们给数据对象添加响应式时,Vue会为这个对象添加一个`__ob__`属性,该属性指向一个Observer实例。这个Observer实例用于追踪依赖和通知变更。在Vue2.x中,响应式原理基于Object.defineProperty,而Vue3.x则使用Proxy。但是无论哪个版本,Vue都会在对象上设置一个不可枚举的属性`__ob__`,以避免被遍历到(例如在JSON.stringify时,不可枚举属性不会被序列化,但当我们直接打印对象时,可以在控制台看到它)。用户可能遇到的问题是:当尝试直接访问带有`__ob__`属性的对象或数组时,有时无法直接获取到值(比如在模板中渲染正常,但在代码中直接访问可能遇到问题),或者需要复制一个没有`__ob__`属性的普通对象。根据引用[4],常见的解决方案是使用`JSON.parse(JSON.stringify(data))`来深拷贝数据,从而去除`__ob__`属性。但要注意,这种方法不能处理函数、循环引用等,而且性能也不是最佳。用户询问`Observer`和`__ob__`相关的编程库或框架,实际上这是Vue.js内部实现的一部分。因此,直接相关的就是Vue.js框架。用户的问题可能是:如何理解Vue中的Observer模式以及如何操作这些带有`__ob__`属性的对象?或者更广泛地说,用户可能想了解响应式原理。因此,我们可以组织回答如下:1.解释`__ob__`和Observer在Vue中的作用。2.为什么我们会在开发中遇到`__ob__`问题?3.如何正确操作响应式数据(例如,避免直接操作`__ob__`,使用Vue提供的方法)。4.当需要普通对象时,如何去除响应式(除了深拷贝,还有其他方法吗?)。同时,生成相关问题以引导用户深入了解。注意:在回答中,我们引用站内资料,需要在段落末尾添加引用标识,如[^1]、[^2]等。</think> ### Vue.js 中的 `__ob__` 和 Observer 解析 在 Vue.js 框架中,`__ob__` 属性是响应式系统的核心实现标志,它指向一个 `Observer` 实例。当 Vue 将普通数据转换为响应式数据时,会自动添加此属性(不可枚举),用于**依赖追踪和更新通知**。以下是技术要点: #### 1. **Observer 的作用** - **响应式原理**:`Observer` 是 Vue 内部类,通过 `Object.defineProperty`(Vue 2)或 `Proxy`(Vue 3)劫持数据,监听属性变化[^2][^3]。 - **依赖管理**:当数据被访问时收集依赖(如组件的渲染函数),数据变更时触发更新[^2]。 - **对象示例**: ```javascript // 原始数据 const rawData = { items: [1, 2, 3] }; // Vue 响应式处理后 const reactiveData = Vue.observable(rawData); console.log(reactiveData); // 输出: { items: [1,2,3], __ob__: Observer } ``` #### 2. **`__ob__` 的常见问题与解决** - **问题场景**: - 直接操作带 `__ob__` 的对象可能返回 `undefined`(如 `reactiveData.items[0]`)[^1]。 - 深度拷贝或序列化时需去除 `__ob__`[^3]。 - **解决方案**: ```javascript // 方法1: 深拷贝转换为纯 JavaScript 对象 const pureArray = JSON.parse(JSON.stringify(reactiveData.items)); // 方法2: Vue 3 使用 toRaw 获取原始对象 (需引入 vue) import { toRaw } from 'vue'; const rawArray = toRaw(reactiveData.items); ``` #### 3. **相关技术库与框架** - **核心库**: - **Vue.js**:内置 `Observer` 系统,是 `__ob__` 的直接来源[^2][^4]。 - **Vuex/Pinia**:状态管理库依赖 Vue 的响应式机制。 - **扩展工具**: - **Immer**:支持不可变数据操作,避免直接修改响应式对象- **lodash.deepClone**:深拷贝替代方案(但需注意性能)。 #### 4. **开发建议** - **避免直接操作 `__ob__`**:它是 Vue 内部属性,直接操作可能破坏响应式。 - **使用官方 API**: - Vue 2:`Vue.observable()` 创建响应式对象- Vue 3:`reactive()` 或 `ref()` 声明响应式数据。 ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值