Bootstrap

Java设计模式——观察者模式

一、什么是观察者模式(Observer模式或观察——订阅模式)

定义对象间一种一对多的依赖关系,当一个对象的类发生改变时,所有依赖于它的对象都得到通知并自动更新。

1.目的

在各个类协作一致的基础上低耦合,提高代码复用率。

2.关键对象

目标(subject) 对象(observer),一个目标可有多个观察者,一个观察者也可以有多个观察目标。一旦目标的状态发生改变,所有的观察者都得到通知。

3.使用条件

        (1)一个对象发生改变时需要通知其他对象

        (2)一个对象必须通知其他对象,而它又不能假定其他对象是谁(互相不知道对方存在而表现地似乎知道),对象之间的低耦合。

        (3)一个抽象模型有两个方面,其中一方面依赖于另一方面,将这两者封装在独立的对象中可以使它们各自独立地改变和复用。

二、观察者模式的结构

Subject 观察目标

——提供注册删除观察对象的接口

——通知观察对象

Observer 观察对象

——观察目标发生改变时为具体的观察对象提供统一的更新接口

ConcreteSubject 具体目标

——在观察对象那里存入具体状态

——当它的状态改变时,向它的各个观察者发出通知

ConcreteObserver 具体观察者

——更新接口使自身状态和目标状态一致

——维护一个指向ConcreteObserver的引用,存储相关状态

三、优缺点

1.目标和观察者之间的抽象耦合

一个目标所知道的仅仅是它有一系列观察者,每个都符合抽象的Observer类的简单接口。不知道任何一个观察者属于哪个具体的类,这样目标和观察者之间的耦合程度是最小的 

2.支持广播通信

3.错误的更新

四、具体示例

示例1. 

观察者: 

package patterns.myobserver;

public interface Observer {
	void update();
}
package patterns.myobserver;

public class ConcreteObserver implements Observer{
	String status;
	String name;

	ConcreteSubject Subject;
	
	public ConcreteObserver(String name,Subject subject) {
		this.name = name;
		this.Subject = (ConcreteSubject) subject;
		//this.Subject.registerObserver(this);
	}

	public void update() {
		status = Subject.getStatus();
		System.out.println(name+"状态更新:"+status);
	}

}

观察对象: 

package patterns.myobserver;

public interface Subject {
	void registerObserver(Observer o);
	void removeObserver(Observer o);
	void notifyObserver();
}
package patterns.myobserver;
import java.util.ArrayList;
public class ConcreteSubject implements Subject{
	String ConcreteSubject;
	String status;
	
	public ConcreteSubject(String status) {
		super();
		this.status = status;
	}
	
	public String getStatus() {
		return status;
	}
	public void setStatus(String status) {
		this.status = status;
		notifyObserver();
	}

	ArrayList<Observer> List = new ArrayList<>();
	public void registerObserver(Observer o) {
		List.add(o);
	}
	public void removeObserver(Observer o) {
		List.remove(o);
	}
	public void notifyObserver() {
		for(Observer u:List)
		{
			u.update();
		}		
	}
	
}

客户端: 

package patterns.myobserver;

public class ClientTest {
	public static void main(String[] args) {
	 
	 Subject boss = new ConcreteSubject("老板来了");
	 Subject delivery = new ConcreteSubject("快递到了");

     Observer user = new ConcreteObserver("用户",boss);
     Observer palyer = new ConcreteObserver("玩家",delivery);
     
     boss.registerObserver(user);
     boss.notifyObserver();
     delivery.registerObserver(palyer);
     delivery.notifyObserver();
     

}
}

运行结果:

示例2.

假设一个场景,当老板进入办公室,办公室的所有用户会接受到“老板来了!” 的信息,而快递到了的时候,用户和玩家都接收到“快递到了!”的信息。

接口,抽象观察对象和抽象观察者 

package patterns.observer;

public interface Subject {
	void notifyTo();
	void register(Observer u);
}
package patterns.observer;

public interface Observer {
	void update(String status);
}
package patterns.observer;
import java.util.ArrayList;
public class BossCome implements Subject{
	String status;
	ArrayList<Observer> userList = new ArrayList<>();
	
	public BossCome(String status) {
		super();
		this.status = status;
	}
	public void register(Observer u)
	{
		userList.add(u);
	}
	public void notifyTo()
	{
		for(Observer u:userList)
		{
			u.update(status);
		}
	}
}

具体观察对象:快递、老板 

package patterns.observer;
import java.util.ArrayList;
public class Delivery implements Subject{
	String status;//快递
	ArrayList<Observer> userList = new ArrayList<>();
	public Delivery(String status) {
		this.status = status;
	}
	public void register(Observer u)
	{
		userList.add(u);
	}
	public void notifyTo()
	{
		for(Observer u:userList)
		{
			u.update(status);
		}
	
	}
}

具体观察者:玩家、用户 

package patterns.observer;

public class Players implements Observer{
	String name;
	public Players(String name) {
		super();
		this.name = name;
	}
	public void update(String status) {
		System.out.println("玩家"+this.name+status);
	}

}
package patterns.observer;

public class User implements Observer{
	String name;
	public User(String name) {
		super();
		this.name = name;
	}
	public void update(String status) {
		System.out.println("用户"+this.name+status);
		
	}
}
package patterns.observer;

public class ClientTest {

	public static void main(String[] args) {
	Observer tony = new User("Tony");
	Observer tom = new Players("Tom");

	Delivery d = new Delivery("快递到了");
	BossCome g = new BossCome("老板来了");
	d.register(tony);
	d.register(tom);
	d.notifyTo();
	g.register(tom);
	g.notifyTo();
	}

}

运行结果:

本博客资料、代码来源于设计模式[Design_Pattern]可复用面向对象的软件的基础和网络,课上教学等,本博客仅用于个人学习,可能存在纰漏,敬请批评指正。

;