设计模式-观察者模式

UML类图

在这里插入图片描述

使用场景

对象B会随着对象A的状态的改变而改变,此时可使用观察者模式,即B作为观察者,A作为通知者,为了让通知者不耦合观察者,所以一般而言都会将观察者抽象。值得注意的是,当B随着A的状态的改变而改变时,C随着B的状态的改变而改变时,当D随着C的状态的改变而改变时,,,即这样的关系比较长时,若中间一个结点出现问题会导致后面其他结点后面的状态不能正常变化,这时一般用异步。

代码实现

通知者抽象

//通知者中使用一个集合存放所有观察者对象
import java.util.ArrayList;
import java.util.List;
public abstract class Subject {
	private List<Observer> observers = new ArrayList<Observer>();
	public void attach(Observer observer){
		observers.add(observer);
	}
	public void dettach(Observer observer){
		observers.remove(observer);
	}
	public void awake(){
		for (Observer observer : observers) {
			observer.update();
		}
	}
}

观察者抽象

//抽象的方法中应该具有更新状态的抽象方法
public abstract class Observer {
	public abstract void update();
}

通知者的具体实现

//通知者中应该有自己的状态字段
public class ConcreteSubject extends Subject{
	private String subjectState;
	public String getSubjectState(){
		return subjectState;
	}
	public void setSubjectState(String subjectState){
		this.subjectState = subjectState;
	}
}

观察者具体实现

public class ConcreteObserver extends Observer{
	//观察者自身的特殊字段
	private String name;
	//观察者的状态
	private String observerState;
	//具体的通知者,需要该字段主要是为了在update中获取通知者的状态
	private ConcreteSubject subject;
	public ConcreteObserver(ConcreteSubject subject,String name){
		this.subject = subject;
		this.name = name;
	}
	@Override
	public void update(){
		this.observerState = this.subject.getSubjectState();
		System.out.println(String.format("观察者%s的新状态是%s",this.name,this.observerState));
	}
	public void setSubject(ConcreteSubject subject){
		this.subject = subject;
	}	
	public ConcreteSubject getSubject(){
		return subject;
	}
}

Main客户端

public class Main {
	public static void main(String[] args) {
		ConcreteSubject s = new ConcreteSubject();
		s.attach(new ConcreteObserver(s,"X"));
		s.attach(new ConcreteObserver(s, "Y"));
		s.attach(new ConcreteObserver(s, "Z"));
		s.setSubjectState("ABC");
		s.awake();
	}
}

输出
观察者X的新状态是ABC
观察者Y的新状态是ABC
观察者Z的新状态是ABC

注意
现在是ConcreteObserver观察ConcreteSubject,当还存在ConcreteObserver2需要随着ConcreteObserver的状态的改变而改变时,那么只需ConcreteObserver继承Subject,让ConcreteObserver2继承Observer即可,从而可让ConcreteObserver作为通知者通知ConcreteObserver2。在java中由于没有多继承,此时需要将Observer修改成接口。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值