设计模式-观察者模式

观察者模式:具体代码请参考java.util.Observer和java.util.Observable



 观察者模式很简单,目标很明确:当被观察者(Observable111)中的数据变更时,即使通知其下所有的观察者(Observer11)进行变更(update)。

 因此,被观察者需要提供  添加观察者,删除观察者,通知观察者等方法,如上类图。

结构很简单,具体不介绍,java.util包中提供了观察者和被观察者的基础类和接口。下面主要说明下这些类中模糊的地方

public class SubjectObservable extends Observable {
    private String name;
    private String type;
    private String colour;
    private double price;

    /**
     * 通过该方法设置变更内容
     * setChange()方法用来标记是否进行变更,一般情况只需要调用,但如果遇到有条件的变更时,比如当值大于某个值时才变更,可以先判断条件,然后再setChange
     * notifyObservers() 当变更发生时,通过setInfo将所有的变更初始化好,并通知观察者进行变更,但观察者需要变更什么内容,则由观察者自己定义
     * notifyObservers(Object args) 该方法notifyObservers(),区别在于由可观察者SubjectObservable推送变更内容,观察者被动接受,类似于广播
     * @param name 要变更的数据
     * @param type 要变更的数据
     * @param colour 要变更的数据
     * @param price 要变更的数据
     */
    public void setInfo(String name,String type,String colour,double price){
        this.name = name;
        this.type = type;
        this.colour = colour;
        this.price = price;
        setChanged();
        notifyObservers();
//        notifyObservers(name);
    }
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getType() {
        return type;
    }

    public void setType(String type) {
        this.type = type;
    }

    public String getColour() {
        return colour;
    }

    public void setColour(String colour) {
        this.colour = colour;
    }

    public double getPrice() {
        return price;
    }

    /**
     * 当price变更时,会通知观察者进行变更(观察者属于被动接受消息)注释部分是这样的
     * @param price
     */
    public void setPrice(double price) {
        this.price = price;
//        this.setChanged();
//        this.notifyObservers(price);
    }
}

 

 如上述注释部分,setInfo来设置需要通知观察者变更的内容,这些内容你可以自己定义,比如爬虫网站数据,发送请求回传的数据等

其中setChange方法是通知观察者的一个标记,因为如果是实时数据,那么通知会很频繁,而观察者可能不需要如此频繁,则可以扩展setChange方法,设置一个判断条件,比如5分钟变更一次等

notifyObservers方法,java.util提供了2个方法:setObservers()和setObservers(Object arg)方法,这2个方法的区别如注释,一个是强制推送给观察者,一个是观察者自己定义要获取的数据

下面是一个观察者的实现

public class Observer2 implements Observer {
    private Observable observable;
    private String name;
    private double price;
/**
     * 构造方法
* 定义其使用的可观察者
* 并将当前观察者添加到可观察者中
* @param observable
*/
public Observer2(Observable observable){
        this.observable = observable;
observable.addObserver(this);
}

    /**
     * 实现update方法
* @param o 可观察者对象
* @param arg 变更的参数  由Observers中notifyObservers(Observer o,Object arg)传递过来的变更的对象
*/
@Override
public void update(Observable o, Object arg) {
        if(o instanceof SubjectObservable){
            SubjectObservable subjectObservable = (SubjectObservable)o;
/**
             * 观察者自己定义需要获取的数据
*/
this.name = subjectObservable.getName();
            this.price = subjectObservable.getPrice();
System.out.println("name has changed to "+name+",price has changed to "+price);
}
    }
}

 

 BUG:虽然java.util中提供了观察者的方式,但是该方式存在很多BUG

1.Observers竟然是一个类,java是单继承,这样就会出现很多不方便的地方。

2.setChange方法是protected,意味这你要使用它必须继承他,不能将Observable的实例组合到你自己的对象中。如:在你定义的class中定义属性  private SubjectObservable oo; oo.setChange();这样违背了策略模式中的多用组合,少用继承的原则。

3.setChange中的changed是私有的,意味着,如果我们是有条件性质的推送通知,那么只能在之前添加判断方法,而不能通过重写setChange方法来实现。虽然这玩意其实没啥影响。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值