当对象间存在一对多关系时,则使用观察者模式(Observer Pattern)。比如,当一个对象被修改时,则会自动通知它的依赖对象。观察者模式属于行为型模式。
1、适用场景
一个对象(目标对象)的状态发生改变,所有的依赖对象(观察者对象)都将得到通知,进行广播通知。
2、代码实现
观察者模式使用三个类 Subject、Observer 和 Client。Subject 对象带有绑定观察者到 Client 对象和从 Client 对象解绑观察者的方法。我们创建 Subject 类、Observer 抽象类和扩展了抽象类 Observer 的实体类。
ObserverPatternDemo,我们的演示类使用 Subject 和实体类对象来演示观察者模式。
(1)结构图
(2)实现代码
步骤 1
创建 Subject 类。
Subject.java
import java.util.ArrayList; import java.util.List; public class Subject { private List<Observer> observers = new ArrayList<Observer>(); private int state; public int getState() { return state; } public void setState(int state) { this.state = state; notifyAllObservers(); } public void attach(Observer observer){ observers.add(observer); } public void notifyAllObservers(){ for (Observer observer : observers) { observer.update(); } } }
步骤 2
创建 Observer 类。
Observer.java
public abstract class Observer { protected Subject subject; public abstract void update(); }
步骤 3
创建实体观察者类。
BinaryObserver.java
public class BinaryObserver extends Observer{ public BinaryObserver(Subject subject){ this.subject = subject; this.subject.attach(this); } @Override public void update() { System.out.println( "Binary String: " + Integer.toBinaryString( subject.getState() ) ); } }
OctalObserver.java
public class OctalObserver extends Observer{ public OctalObserver(Subject subject){ this.subject = subject; this.subject.attach(this); } @Override public void update() { System.out.println( "Octal String: " + Integer.toOctalString( subject.getState() ) ); } }
HexaObserver.java
public class HexaObserver extends Observer{ public HexaObserver(Subject subject){ this.subject = subject; this.subject.attach(this); } @Override public void update() { System.out.println( "Hex String: " + Integer.toHexString( subject.getState() ).toUpperCase() ); } }
步骤 4
使用 Subject 和实体观察者对象。
ObserverPatternDemo.java
public class ObserverPatternDemo { public static void main(String[] args) { Subject subject = new Subject(); new HexaObserver(subject); new OctalObserver(subject); new BinaryObserver(subject); System.out.println("First state change: 15"); subject.setState(15); System.out.println("Second state change: 10"); subject.setState(10); } }
步骤 5
验证输出。
First state change: 15 Hex String: F Octal String: 17 Binary String: 1111 Second state change: 10 Hex String: A Octal String: 12 Binary String: 1010
3、使用Java自带的Observer接口实现
import java.util.Observable;
import java.util.Observer;
class House extends Observable{ //增加可被观察的事物,如房子
private float price;//定义房价
public float getPrice() {
return price;
}
public void setPrice(float price) {
super.setChanged(); //定义状态已被改变
super.notifyObservers(price);//定义改变主题,该主题会被通知到每个观察者
this.price = price;
}
public String toString(){
return Float.toString(price);
}
}
//import java.util.Observer
class HouseObser implements Observer{ //增加观察者
private String name;
public HouseObser(String name){
this.name = name;
}
@Override
public void update(Observable o, Object arg) {
// TODO Auto-generated method stub
System.out.println("现在价格:"+ o);
System.out.println(this.name+" 得到最新价格 "+ arg);
}
}
public class ObserverDemo2 {
public static void main(String[] args){
House h = new House();
HouseObser hb1 = new HouseObser("观察者1");
HouseObser hb2 = new HouseObser("观察者2");
HouseObser hb3 = new HouseObser("观察者3");
h.addObserver(hb1);
h.addObserver(hb2);
h.addObserver(hb3);
h.setPrice(100);
}
}
现在价格:0.0
观察者3 得到最新价格 100.0
现在价格:0.0
观察者2 得到最新价格 100.0
现在价格:0.0
观察者1 得到最新价格 100.0