设计模式学习-观察者模式

本文介绍了观察者模式,一种用于处理对象间依赖关系的设计模式。定义了一对多的依赖,当一个对象状态变化时,其他依赖对象会被通知并响应。内容包括模式的定义、结构、实例、优缺点及适用场景。例如,在游戏开始功能中,游戏倒计时结束时,战队成员会收到通知。观察者模式的优点是解耦合,支持广播通信,符合开闭原则,但应注意避免循环调用导致系统崩溃。

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

观察者模式

在软件系统中,各个对象并不是孤立存在的,经常会出现一个对象的状态发生了变化,会导致其他一个或者多个存在依赖关系的对象跟随变化的场景。观察者模式用来描述对象之间的依赖关系,为实现多个对象之间的联动提供了一种解决方案。

定义

观察者模式定义了一种一对多的依赖关系,每当一个对象的状态发生变化的时候,其他依赖对象都会得到通知并发生相应变化。

结构

观察者模式通常包含观察者和观察目标两个部分。

  • Subject(观察目标):它是被观察的对象,内部定义了一个观察者集合以及添加观察者、删除观察者、通知观察者的方法
  • ConcreteSubject(具体观察目标):观察目标的继承类或者实现类。内部定义了某个经常发生变化的状态以及状态的改变方法,状态改变后,会调用相应的通知观察者的方法
  • Observer(观察者):观察者将对观察目标的状态改变做出反应,内部声明了update方法,一般被定义为接口,由实现类定义具体的update方法
  • ConcreteObserver(具体观察者):观察者的实现类,定义了具体的update方法,当观察目标的状态发生变化的时候被执行
    在这里插入图片描述

实例

设计一个简单的游戏开始功能。游戏倒计时,当倒计时到0时,战队成员接到通知出发。当游戏时间到0时,战队成员接到通知停止游戏。

package observer;

import java.util.ArrayList;
import java.util.List;

public abstract class BattleTeam {

	private List<Member> memberList = new ArrayList<>();
	
	public void addMember(Member member) {
		this.memberList.add(member);
	}
	
	public void removeMember(Member member) {
		this.memberList.remove(member);
	}
	
	public void changeState(boolean startStatus) {
		memberList.forEach(m->m.executeCommand(startStatus));
	}
}

package observer;

public class ConcreteBattleTeam extends BattleTeam{

	private boolean startStatus = false;
	
	public void start() {
		this.startStatus = true;
		this.changeState(startStatus);
	}
	
	public void end() {
		this.startStatus = false;
		this.changeState(startStatus);
	}
	
}

package observer;

public interface Member {

	void executeCommand(boolean startStatus);
}

package observer;

public class ConcreteMember implements Member{

	private String name;
	
	public ConcreteMember(String name) {
		super();
		this.name = name;
	}
	
	@Override
	public void executeCommand(boolean startStatus) {
		if (startStatus) {
			System.out.println(name + "出发");
		} else {
			System.out.println(name + "停止");
		}
	}


}

package observer;

public class Test {

	public static void main(String[] args) throws InterruptedException {
		BattleTeam team = new ConcreteBattleTeam();
		
		Member zhangsan = new ConcreteMember("张三");
		Member lisi = new ConcreteMember("李四");
		Member wangwu = new ConcreteMember("王五");
		Member zhaoliu = new ConcreteMember("赵六");
		
		team.addMember(zhangsan);
		team.addMember(lisi);
		team.addMember(wangwu);
		team.addMember(zhaoliu);

		for (int i = 5; i > 0; i--) {
			System.out.println("距离开始" + i + "秒");
			Thread.sleep(1000);
		}
		team.changeState(true);
		Thread.sleep(2000);
		team.changeState(false);
	}
}

优点

  • 实现了数据表示层和数据逻辑层的分离,使得功能进行解耦
  • 在观察目标和观察者之间建立一个抽象的耦合,观察目标不需要具体了解观察者
  • 支持广播通信,观察目标像所有注册的观察者进行通知,简化了一对多的设计难度
  • 符合开闭原则,增加新的观察者的时候不需要堆观察目标进行改动
缺点
  • 观察目标和观察者之间尽量不能存在相互调用,不然可能触发循环导致系统崩溃
  • 观察者模式没有相应的机制让观察者知道所观察的目标对象是怎么发生变化的,只知道变化的结果

使用场景

  • 一个抽象模型有两个方面,一个方面依赖于另一个方面的变化,可以将两个方面拆分,使其独立发展
  • 一个对象的改变会导致一个或者多个对象也发生相应的变化,而且这些对象个数可能动态改变
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值