java+设计人物,Java设计模式—观察者(Observer)详解

观察者模式的定义:

观察者模式定义了一种一对多的依赖关系,被观察者一般称为主题,一个主题对象会有多个观察者,一旦主题更新了信息,就会推送到各个观察者处。

举一个生活中常见的例子:

fff6c98081bf8904098fb5e1bd59ff4b.gif

3个人(观察者)都想买房(主题对象),于是他们都订阅了某楼盘的房价信息,一旦楼盘的房价变动,这3个人都会受到最新的房价。这就是观察者模式的作用。

其实Java中,已经内置有实现观察者模式的api。但我们先来自己实现观察者模式。

自行实现观察者模式

观察者模式的组成

抽象主题角色:抽象主题提供一个接口,可以增加和删除观察者角色。

具体主题角色:当具体主题内部的信息更新时,通知所有注册的观察者,使他们收到消息

抽象观察者角色:为所有具体的观察者定义一个接口,在得到主题的通知时更新自己。

具体观察者角色:该角色实现抽象观察者角色所要求的更新接口。

下面是具体的实例(该实例以购房为情景)

首先看工程目录图:

fff6c98081bf8904098fb5e1bd59ff4b.gif

抽象主题角色:

public interface Subject {

// 添加主题(被观察者)

public void addObserver(Observer observer);

// 移除主题(被观察者)

public void removeObserver(Observer observer);

// 更新所有观察者

public void notifyObserver();

}

具体主题角色:

public class House implements Subject {

private List observers = new ArrayList<>();

private float price;

public House(float price){

this.price = price;

}

@Override

public void addObserver(Observer observer) {

observers.add(observer);

}

@Override

public void removeObserver(Observer observer) {

observers.remove(observer);

}

@Override

public void notifyObserver() {

if(observers != null){

for(Observer observer : observers){

observer.update(price);

}

}

}

public void updatePrice(float price){

this.price = price;

notifyObserver();

}

public String toString(){

return "房价为:" + price;

}

}

抽象观察者角色:

public interface Observer {

public void update(float price);

}

具体观察者角色:

public class HouseObserver implements Observer{

private String observerName;

//为不同的房子价格观察者记录名字

public HouseObserver(String observerName){

this.observerName= observerName;

}

@Override

public void update(float currentPrice) {

System.out.println( observerName+ " 观察到当前的价格为:" + currentPrice);

}

}

测试代码

public class testObserver {

public static void main(String args[]){

//设置初始价格

House house = new House(10000);

HouseObserver observer1 = new HouseObserver("买房者A");

HouseObserver observer2 = new HouseObserver("买房者B");

HouseObserver observer3 = new HouseObserver("买房者C");

//加入观察者观察房价

house.addObserver(observer1);

house.addObserver(observer2);

house.addObserver(observer3);

//初始房价

System.out.println(house);

//更新房价

house.updatePrice(6666);

//更新后房价

System.out.println(house);

}

}

下面是运行的结果:

房价为:10000.0

买房者A 观察到当前的价格为:6666.0

买房者B 观察到当前的价格为:6666.0

买房者C 观察到当前的价格为:6666.0

房价为:6666.0

具体的解释都在代码中,也不一一解释了。

关键在于 —–> house.updatePrice(6666) 主题更新,每一个买房者都接收到了通知,并且打印了出来。

Java内置观察者模式

Java中提供了一个Observerable类和Observer接口,这两个类就相当于上面所提到的 抽象主题角色 和 抽象观察者角色。

需要注意的地方:

Observerable是一个类,Observer是一个接口,所有具体主题角色都要继承Observerable,所有juice观察者角色都要实现Observer接口。

具体主题角色信息改变了,它必须调用setChanged()方法。

具体主题角色准备通知观测程序它的改变时,它必须调用notifyObservers()方法,这导致了在观测对象中对update()方法的调用。

下面来看具体的实例(也是基于购房实例)

工程结构:

fff6c98081bf8904098fb5e1bd59ff4b.gif

具体主题角色:

public class House extends Observable {

private float price;

public House(float price) {

this.price = price;

}

public float getPrice() {

return price;

}

public void setPrice(float price) {

// 标记已经变化

super.setChanged();

// 设这价格被改变

super.notifyObservers(price);

// 更新价格

this.price = price;

}

public String toString() {

return "房价为:" + price;

}

}

具体观察者角色:

public class HouseObserver implements Observer {

private String houseName;

// 为不同的房子价格观察者记录名字

public HouseObserver(String houseName) {

this.houseName = houseName;

}

@Override

public void update(Observable subject, Object price) {

if (price instanceof Float) {

float currentPrice = (Float) price;

System.out.println(houseName + " 观察到当前的价格为:" + currentPrice);

}

}

}

测试代码

public class testObserver {

public static void main(String args[]) {

// 设置初始价格

House house = new House(10000);

HouseObserver observer1 = new HouseObserver("买房者A");

HouseObserver observer2 = new HouseObserver("买房者B");

HouseObserver observer3 = new HouseObserver("买房者C");

// 加入观察者观察房价

house.addObserver(observer1);

house.addObserver(observer2);

house.addObserver(observer3);

// 初始房价

System.out.println(house);

// 更新房价

house.setPrice(6666);

// 更新后房价

System.out.println(house);

}

}

运行结果如下:

房价为:10000.0

买房者C 观察到当前的价格为:6666.0

买房者B 观察到当前的价格为:6666.0

买房者A 观察到当前的价格为:6666.0

房价为:6666.0

说明观察者模式确实起到了作用。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值