设计模式之观察者模式(Observer Pattern)

本文深入解析了观察者模式,一种让对象间建立一对多依赖关系的设计模式,当一个对象状态改变时,所有依赖对象自动更新。文章通过代码示例详细说明了Subject、Observer等角色的实现,以及模式在《水浒传》故事中的应用。
  • 观察者模式定义
    Define a one-to-many dependency between objects so that when one object changes state, all its dependents are notified and updated automatically. 定义对象之间一种一对多的依赖关系,使得每当一个对象改变状态,则所有依赖于它的对象都会得到通知并被自动更新。

  • 观察者模式通用类图
    在这里插入图片描述
    通过上面的类图,我们可以看到观察模式主要有四个角色:

    • Subject被观察者:定义被观察者必须实现的职责,它必须能够动态的增加、取消观察者。将attach、detach、notify是三个方法放在一个容器里,一般用Vector(之所以使用Vector而不使用List,是因为多线程操作时,Vector在是安全的,而List则是不安全的),attach方法是向这个容器中添加观察者对象;detach方法是从容器中移除观察者对象;notify方法是依次调用观察者对象的对应方法。
    • Observer观察者:观察者角色一般是一个接口,它只有一个update方法,在被观察者状态发生变化时,这个方法就会被触发调用。
    • ConcreteSubject具体的被观察者:定义被观察者自己的业务逻辑,同时定义对哪些事件进行通知。
    • ConcreteObserver具体的观察者:每个观察者在接收到消息后的处理反应是不同的,每个观察者都有自己的处理逻辑。
  • 观察者模式通用代码
    被观察者

public abstract class Subject {

	private Vector<Observer> obsVector = new Vector<Observer>();

	public void addObserver(Observer o) {
		this.obsVector.add(o);
	}

	public void delObserver(Observer o) {
		this.obsVector.remove(o);
	}

	public void notifyObserver() {
		obsVector.forEach(i -> {
			i.update();
		});
	}
}

具体的被观察者

public class ConcreteSubject extends Subject {

	public void doSth() {
		super.notifyObserver();
	}
}

观察者

public interface Observer {

	void update();
}

具体观察者

public class ConcreteObserver implements Observer{

	@Override
	public void update() {
		System.out.println("接收消息并处理");
	}
}

场景类

public class Client {

	public static void main(String[] args) {
		
		ConcreteSubject subject = new ConcreteSubject();
		
		Observer obs = new ConcreteObserver();
		
		subject.addObserver(obs);
		
		subject.doSth();
	}
}
  • 观察者模式实例类图
    施耐庵写的《水浒传》相信很多人都看过,其中吴用等人 智取生辰纲 这个故事让人印象深刻。故事情节是这样的:在路经黄泥岗时路遇一批贩枣客人,又有一人贩酒而来,而这群贩枣客就是晁盖、吴用等人假扮的,吴用等人假装卖枣稳住杨志等人,白胜扮卖酒汉引诱对方,吴用在杨志放松警惕时下药在瓢里,白胜夺来倒在桶里麻倒对方,智取生辰纲。那么在这个故事中生辰纲就可以看作是被观察者,杨志等人就可以看作是观察者,晁盖、吴用也可以看作是观察者

在这里插入图片描述

  • 观察者模式实例代码
    抽象被观察者
/**
 * 被观察者
 * 
 * @author cm_wang
 *
 */
public abstract class Subject {

	private Vector<Observer> obsVector = new Vector<Observer>();

	public void addObserver(Observer o) {
		this.obsVector.add(o);
	}

	public void delObserver(Observer o) {
		this.obsVector.remove(o);
	}

	public void notifyObserver() {
		obsVector.forEach(i -> {
			i.update();
		});
	}
}

观察者

/**
 * 观察者
 * 
 * @author cm_wang
 *
 */
public interface Observer {

	void update();
}

具体的被观察者,也就是生辰纲

public class shengchengang extends Subject {

	public void doSth() {
		super.notifyObserver();
	}
}

具体的观察者,也就是杨志等人,还有晁盖、吴用等人

public class wuyong implements Observer{

	@Override
	public void update() {
		System.out.println("吴用等人假装卖枣稳住杨志等人");
		System.out.println("吴用在杨志放松警惕时下药在瓢里");
	}
}
public class baisheng implements Observer{

	@Override
	public void update() {
		System.out.println("白胜夺来倒在桶里麻倒对方");
	}
}
public class yangzhi implements Observer{

	@Override
	public void update() {
		System.out.println("杨志等人喝了带蒙汗药的酒,就只能眼睁睁的看晁盖、吴用等人拿走生辰纲");
	}
}

具体场景类

public class Client {

	public static void main(String[] args) {

		shengchengang subject = new shengchengang();

		Observer obs = new yangzhi();
		
		Observer thief = new wuyong();

		Observer thief1 = new baisheng();
		
		// 吴用等人假装卖枣稳住杨志等人
		subject.addObserver(thief);
		// 白胜夺来放有蒙汗药的瓢倒在桶里麻倒对方
		subject.addObserver(thief1);
		// 杨志等人喝了带蒙汗药的酒
		subject.addObserver(obs);
		
		subject.doSth();
	}
}

运行结果:

吴用等人假装卖枣稳住杨志等人
吴用在杨志放松警惕时下药在瓢里
白胜夺来倒在桶里麻倒对方
杨志等人喝了带蒙汗药的酒,就只能眼睁睁的看晁盖、吴用等人拿走生辰纲
  • 观察者模式的优点
    • 观察者与被观察者之间是属于轻度的关联关系,并且是抽象耦合的。
    • 观察者模式是一种常用的触发机制,它形成一条触发链,依次对各个观察者的方法进行处理。
  • 观察者模式的缺点
    • 由于是链式触发,当观察者比较多的时候,性能问题是比较令人担忧的。

参考书籍:设计模式之禅
实例代码放在这里

1) 优秀的程序应该是这样的:阅读时,感觉很优雅;新增功能时,感觉很轻松;运行时,感觉很快速,这就需要设计模式支撑。2) 设计模式包含了大量的编程思想,讲授和真正掌握并不容易,网上的设计模式课程不少,大多讲解的比较晦涩,没有真实的应用场景和框架源码支撑,学习后,只知其形,不知其神。就会造成这样结果: 知道各种设计模式,但是不知道怎么使用到真实项目。本课程针对上述问题,有针对性的进行了升级 (1) 授课方式采用 解+框架源码分析的方式,让课程生动有趣好理解 (2) 系统全面的讲解了设计模式,包括 设计模式七大原则、UML类-类的六大关系、23种设计模式及其分类,比如 单例模式的8种实现方式、工厂模式的3种实现方式、适配器模式的3种实现、代理模式的3种方式、深拷贝等3) 如果你想写出规范、漂亮的程序,就花时间来学习下设计模式吧课程内容和目标本课程是使用Java来讲解设计模式,考虑到设计模式比较抽象,授课采用 解+框架源码分析的方式1) 内容包括: 设计模式七大原则(单一职责、接口隔离、依赖倒转、里氏替换、开闭原则、迪米特法则、合成复用)、UML类(类的依赖、泛化和实现、类的关联、聚合和组合) 23种设计模式包括:创建型模式:单例模式(8种实现)、抽象工厂模式、原型模式、建造者模式、工厂模式。结构型模式:适配器模式(3种实现)、桥接模式、装饰模式、组合模式、外观模式、享元模式、代理模式(3种实现)。行为型模式:模版方法模式、命令模式、访问者模式、迭代器模式、观察者模式、中介者模式、备忘录模式、解释器模式(Interpreter模式)、状态模式、策略模式、职责链模式(责任链模式)2) 学习目标:通过学习,学员能掌握主流设计模式,规范编程风格,提高优化程序结构和效率的能力。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值