观察者设计模式定义了对象间的一种一对多的依赖关系,以便一个对象的状态发生变化时,所有依赖于它的对象都得到通知并自动刷新。我们常用的事件机制内部实现就使用了观察者模式。java类也帮我们实现了观察者模式。下面举实例来讲解观察者设计模式,为了便于更好的理解观察者模式,先自己编写观察者模式,不调用java自带的接口和实现类。
事例:现在人都喜欢网购,当你看上一件商品时你可能会想时时关注商品的价格波动,当该商品的价格变化时希望能收到通知。此时我们就可以利用观察者模式来处理。此时关注的商品是被观察者,而“我们”就是具体的观察者对象
1.自定义观察者模式
定义被观察者对象接口
package com.longpo.observer;
/**
* 被观察者接口
*/
public interface Subject {
//注册一个观察者对象
public void registerObserver(Observer observer);
//移除一个观察者对象
public void removeObserver(Observer observer);
//通知所有观察者更新信息--这里是价格变化时
public void notifyObserver();
}
定义具体的被观察者对象--商品
package com.longpo.observer;
import java.util.ArrayList;
/**
* 具体的被观察者对象--商品
*/
public class Goods implements Subject{
//观察者对象列表
public ArrayList<Observer> lists=new ArrayList<Observer>();
//观察的属性--价格--设置成私有的,改变价格需要调用setPrice方法,从而发出通知
private float price;
public Goods(float price) {
super();
this.price = price;
}
public float getPrice() {
return price;
}
public void setPrice(float price) {
this.price = price;
//价格一发生变化,调用通知方法
notifyObserver();
}
//添加一个观察者
@Override
public void registerObserver(Observer observer) {
lists.add(observer);
}
//移除一个观察者
@Override
public void removeObserver(Observer observer) {
lists.remove(observer);
}
//通知所有观察者进行更新
@Override
public void notifyObserver() {
//通知所有观察者对象
for(int i=0;i<lists.size();i++)
{
lists.get(i).update(price);
}
}
}
定义观察者接口
package com.longpo.observer;
/**
* 观察者接口
*/
public interface Observer {
//价格变化进行更新的方法
public void update(float price);
}
定义具体的观察者类
package com.longpo.observer;
/**
*具体的观察者对象---人
*/
public class Person implements Observer{
public String name;
public Person(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
//收到价格变动后执行的函数
@Override
public void update(float price) {
System.out.println(name+"关注商品的价格变为了:"+price);
}
}
以上我们就实现了观察者设计模式,来测试一下
package com.longpo.observer;
public class Test {
public static void main(String[] args) {
//创建一个被观察者对象--初始价格2000
Goods goods=new Goods(2000);
//定义人对象
Person person=new Person("小明");
Person person1=new Person("小红");
Person person2=new Person("小黑");
//把三人都注册成为观察者
goods.registerObserver(person);
goods.registerObserver(person1);
goods.registerObserver(person2);
//价格发生变化--会自动通知所有观察者对象
goods.setPrice(998);
System.out.println("-------------------------");
goods.removeObserver(person);//小明取消为观察者。。小明不再接收价格变动的通知
goods.setPrice(888);
}
}
运行结果:
2.使用java自带的接口和实现类
定义被观察者对象类继承Observable
package com.longpo.observer.java;
import java.util.Observable;
/**
* java自带的观察者设计模式,通过继承Observable类来实现具体的被观察对象
*/
public class Goods extends Observable {
private float price;//只需要定义自己需要观察的属性,其他方法Observable类已经帮我们实现
public Goods(float price) {
this.price = price;
}
public float getPrice() {
return price;
}
public void setPrice(float price) {
this.price = price;
//通知价格改变
this.setChanged();
//调用更新方法--该方法是Observable的方法--price对应观察者的arg参数
this.notifyObservers(price);
}
}
定义观察者对象类实现Observer接口
package com.longpo.observer.java;
import java.util.Observable;
import java.util.Observer;
/**
* 通过实现java.util.Observer接口实现具体的观察者对象
*/
public class Person implements Observer{
private String name;
public Person(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
/**
* Observable o:被观察者类
* Object arg :被观察者传递的参数
*/
public void update(Observable o, Object arg) {
//当Goods调用this.notifyObservers(price)时
System.out.println(name+"关注的商品的价格变化为:"+arg);
}
}
测试代码
package com.longpo.observer.java;
public class Test {
public static void main(String[] args) {
Goods goods=new Goods(2000);
Person person=new Person("小红");
Person person1=new Person("小明");
Person person2=new Person("小黑");
//三人都添加关注
goods.addObserver(person);
goods.addObserver(person1);
goods.addObserver(person2);
goods.setPrice(988);
System.out.println("----------------------");
goods.deleteObserver(person1);//person1取消关注
goods.setPrice(999);
}
}
运行结果: