观察者模式

本文深入讲解观察者模式,一种在软件工程中广泛使用的设计模式。它允许对象在状态发生变化时,自动通知其依赖者,从而实现解耦。文章通过生动的例子,如婴儿摔倒和自助餐烤鱼场景,阐述了观察者模式的一对多关系特性,以及如何在实际编程中应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

设计模式是一种优秀的编程思想,能帮助你写出优雅的高质量的代码,所以编程者们学习设计模式也是非常有必要的。
曾经我对算法和设计模式这些是不太感冒的,觉得只要自己看懂了,功能实现了又没问题就足够,别人接手觉得改不了那是别人水平问题,后来吃过苦头接手过别人代码才知道,不管前后端都一定要写出优质代码,对自己负责也对别人负责。

下面开始正式介绍观察者模式,观察者模式又被称为广播订阅模式,模型视图模式,其实简单点说就是:一个被大家关注的东西发生改变后,所有关注它的人都会做出相对应反应。
比如:一个婴儿在地上爬,那么父母,爷爷奶奶,三姑六婆围在身边的,都是观察者,婴儿不小心摔一下,他们都会马上做出反应。这就是观察者模式。
又或者:你去吃自助餐,厨师在烤龙虾,你跟一群虎视眈眈的大胃王围着厨师观察,等到厨师一说烤好了,大家就扑上去抢。

好了,通过上面两个例子,不难总结出来几个规律:

1:观察者模式是一对多的关系。

2:被观察者出现某种行为后会告知全部观察者。

3:观察者可以根据自己实际需求对触发行为做出具体处理反应。

4:观察者模式触发后就不能手动中断,是一种链式触发机制,通知会一直送到每个观察者那里。

那么,这个设计模式有什么好处呢?那就是,某种资源如果发生改动时候大家都是需要知会的,那么不用什么轮询和定时器去不停询问改变状态(太烦了),而是被观察者在发生改变后,触发通知行为,去主动通知它的全部观察者。用最少的代码,实现最好的解耦效果。这就是设计模式的好处!

下面请看演示(用自助餐举例子):

首先我定义一个食客的接口

public interface Customer {
public void eat(); // 来烧烤店那肯定都是为了吃,难道还dance跳舞咩?
}

创造出多个食客ABCD。。。(其实这里用抽象类更符合要求,具体操作可以看我另外一篇博客接口与抽象类区别)

public class A豪放顾客 implements Customer {
@Override
public void eat(){
System.out.println(“疯狂吃鱼啊!!!”);
};
}

public class B豪放顾客 implements Customer {
@Override
public void eat(){
System.out.println(“斯文地吃鱼~~~”);
};
}
。。。。。。。。。。。。

然后我定义一个厨师在烹饪烤鱼动作的接口

public interface 烤鱼Fish {
public void 烤熟状态Status(A a); // 烤熟了才能吃
public void 等待吃烤鱼的食客List(B b); // 观察者们,都在眼巴巴等吃
public void 宣布可以吃了Call(C c); // 烤熟了才能调用宣布方法
}

现在实现烤鱼动作接口,开始烤鱼

public class 烤鱼Cooking implement 烤鱼Fish {

// 厨师用小本本记下全部食客
private List<顾客Customer> cList = new ArrayList<顾客Customer>();

//有新的客人进来
@Override
public void 等待吃烤鱼的食客List(B b){
cList.add( b );   //增加食客

}

// 重写实现烤鱼的方法
@Override
public void 烤熟状态Status(A a){
if ( a === 100) {
	// 完全烤熟了,通知小本子上的顾客抢着吃
	this.宣布可以吃了Call(C cList);
} else {
// 继续烹饪
}

}
public void 宣布可以吃了Call(C cList){
for ( 顾客Customer of cList ){
顾客Customer.eat(); // 食客开始吃!
}
}

}

这个例子不太恰当,其实是全部食客可以异步进行吃操作,不用等一个吃完下一个再吃,下面罗列一些观察者模式的缺点:

缺点:观察者模式概念简单,真正开发时逻辑复杂情况下设计复杂。开发和调试难(你设想一下设计好这个模式后,测试要开多个端口去跑,看看各个观察者的反应输出是否一致,是否每一个都通知到位),其次最重要的是通知方式一般是顺序执行,某些观察者的处理逻辑复杂,执行速度慢,会拖延后面的通知执行时间,最终导致执行时间较长,除非是些无需等待返回值的,可以异步处理(例如Node中异步回调asycn 和 等待await)。在上面例子中,我们可以看见观察者们不能预先知道鱼什么时候烤熟而作准备,也不能知道鱼是怎么发生了改变的,他们得到的仅仅是一个简单的通知,丢失了烹饪(数据发生改变)的过程。

好了,观察者设计模式就介绍到这里,如果有说得不对的地方欢迎指出来,或者有哪里讲得不太明确也可以告诉我哦。留言必回,谢谢大家,喜欢的点点关注哈!
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值