java观察者(Observer)模式

    观察者模式:
    试想,在电子商务网站上,一个用户看中了一件一份,但是当时衣服的价格太贵,你需要将衣服收藏,以便等衣服降价时自动通知该用户。这里就是典型的观察模式的例子。
    1.观察者模式的定义:
       定义了一种对象之间的依赖关系,当一个对象(主题)发生改变时,它所有的依赖者(观察者)会收到主题状态改变的通知,并更新自己的状态。

       观察者模式让主题和观察者松耦合。主题不知道观察者的实现细节;任何时候在增加观察者的时候,可以随时增加,而不需要改变主题的代码,当然删除观察者也是一样。在开始的例子中,衣服便是主题(Subject),用户便是观察者(Observer),用户将衣服加收藏的过程便是观察者在主题注册那里的过程。

    2.观察者模式的类图:

     

     3.java提供了内置的观察者模式:Observer接口和Observerable类;为了理解观察模式,先不用这个内置方法,先用常规的方法实现以下上述例子:

package observer;
//主题接口
public interface Subject {

	public void addObserver(Observer observer);
	public void deleteObserver(Observer observer);
	public void notifyObserver();
}

package observer;

//观察者接口
public interface Observer {

	public double getOldPrice();
	public void update(double price);
}

package observer;
/*
 * 具体的主题,concrete subject
*/
import java.util.ArrayList;
import java.util.List;
public class ClotheSubject implements Subject{

	List<Observer> observers ;
	double price;
	public ClotheSubject()
	{
		observers = new ArrayList<>();
	}
	@Override
	public void addObserver(Observer observer) {
		// TODO Auto-generated method stub
		observers.add(observer);
	}

	@Override
	public void deleteObserver(Observer observer) {
		// TODO Auto-generated method stub
		int index = (int)observers.indexOf(observer);
		if(index >= 0)
		observers.remove(index);
	}

	@Override
	public void notifyObserver() {
		// TODO Auto-generated method stub
		for(int i = 0;i < observers.size();i++)
		{
			Observer observer = (Observer)observers.get(i);
			observer.update(price);
		}
	}
	
	public void setPrice(double price)
	{
		this.price = price;
		notifyObserver();
	}

	
}
package observer;

public class ClotheObserver implements Observer{

	Subject subject;
	double price = 100.00d;//原始价格
	public ClotheObserver(Subject subject)
	{
		this.subject = subject;
		subject.addObserver(this);
	}
	@Override
	public void update(double price) {
		// TODO Auto-generated method stub
		if(price<this.getOldPrice())
		System.out.println("您上次看中衣服的价格变为:"+price+",请抓紧购买!");
		this.price = price;
	}
	@Override
	public double getOldPrice() {
		// TODO Auto-generated method stub
		return price;
	}

}
测试代码:
package observer;

public class Client_test {

	public static void main(String args[])
	{
		ClotheSubject clothe_subject = new ClotheSubject();
		Observer clothe_observer = new ClotheObserver(clothe_subject);
		clothe_subject.setPrice(10.00d);
		clothe_subject.setPrice(90.00d);
		clothe_subject.setPrice(20.00d);
	}
}

      4.java自身提供的内置观察者模式:java.util提供了observer接口和Observerable类,对象只需要实现观察者接口,便可以成为观察者,然后调用Observerable的addObserver方法,便加入主题中。下面是用内置观察者模式重新修改上例代码:

      主题类:

package observer;
/*
 * 具体的主题,concrete subject
*/
import java.util.Observable;
public class ClotheSubject extends Observable{

	double price;
	public ClotheSubject()
	{
	}
	public void priceChanged()
	{
		setChanged();
		notifyObservers();//Observable中的方法,会调用观察者的update方法
	}
	
	public void setPrice(double price)
	{
		this.price = price;
		priceChanged();
	}

	public double getPrice()
	{
		return price;
	}
}
观察者类:

package observer;
import java.util.Observable;
import java.util.Observer;
public class ClotheObserver implements Observer{

	Observable observerable;
	double price = 100.00d;
	public ClotheObserver(Observable observerable)
	{
		this.observerable = observerable;
		//将自己注册为观察者
		observerable.addObserver(this);
	}
	@Override
	public void update(Observable o, Object arg) {
		// TODO Auto-generated method stub
		if(o instanceof ClotheSubject)
		{
			ClotheSubject clothesubject = (ClotheSubject)o;
			if(price > clothesubject.getPrice())
				display(clothesubject.getPrice());
			this.price = clothesubject.getPrice();
		}
	}
	
	public void display(double price)
	{
		System.out.println("您上次看中衣服的价格变为:"+price+",请抓紧购买!");
	}
	
}
测试代码:

package observer;

public class Client_test {

	public static void main(String args[])
	{
		ClotheSubject clothe_subject = new ClotheSubject();
		ClotheObserver clothe_observer = new ClotheObserver(clothe_subject);
		clothe_subject.setPrice(90.00d);
		clothe_subject.setPrice(80.00d);
	}
}



原文地址:https://www.cnblogs.com/sunp823/p/5601411.html