Java设计模式——3.观察者模式(Observer)

3.观察者模式

3.1概述

观察者模式又称发布订阅模式,是对象的行为模式。观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监视着被观察者的状态,当被观察者的状态发生变化,会通知所有观察者,并让其自动更新自己。

现实中有没有这样的例子呢?如智能监控,系统会根据采集到的画面信息做出不同的措施;气象局要监测气温和空气质量,随其变化来发布不同的信息。

下面通过一个电商实例来模拟观察者模式。在现实中,有些条件发生了变化,其他的行为也要发生变化,我们可以用if语句来处理。现在,有一个商家生产一些产品,它和一些电商平台合作,每当有新产品时,就会把这些产品推送到电商,现在商家只和京东、淘宝合作,于是有这样的伪代码:

if (产品库有新产品){
    推送新产品到京东;
    推送新产品到淘宝;
}

如果商家又和其他平台合作了,就要做如下修改:

if (产品库有新产品){
    推送新产品到京东;
    推送新产品到淘宝;
    推送新产品到当当;
    推送新产品到拼多多;
}

如果按这种方法,这时合作平台又发生变化,还要继续在if语句中修改逻辑。平台很少还可以,如果合作平台多达数百家,那这个if的逻辑就十分复杂了,这时如果一家平台出现异常,那也是无法再往下进行了。代码耦合度高,不利于维护,难拓展,不同的电商应该由不同的团队来负责,这些团队又共同负责同一段代码,造成责任不清。

这时采用观察者模式就有优势了,观察者模式更易拓展,责任也更加清晰。首先,把每个电商平台接口视为一个观察者,每个观察者都能观察到产品列表(被监听对象)。当商家发布新商品时,就会发送到这个产品列表上,于是产品列表(被监听对象)就发生了变化,这时就可以触发各个电商接口(观察者)发送新产品到合作的电商。这个过程的示例图如下:

 这样,一个对象(电商接口)会去监听另外一个对象(产品列表),当被监听对象(产品列表)发生变化时,对象(电商接口)就会触发一定的行为,以合适变化的逻辑模式,称为观察者模式,电商接口被称为观察者或监听者,而产品对象被称为被观察者或者被监听者。

这样的好处很明显,程序中不再出现if语句,观察者会根据被观察对象的变化而做出对应的行为,每个电商的接口只需要维护自己的逻辑,不用耦合在一起,同时责任也是明确的,产品团队只需要维护产品列表,电商团队可以通过增加观察者去监听产品的电商接口,不会带来if语句导致的责任不清的情况。 

3.2实例

观察者模式需要同时存在观察者和被观察者双方,观察者可以是多个。被观察者需要继承java.util.Observable类,观察者实现java.util.Observer接口的update方法。

一个产品列表类(被观察者)代码如下:

public class ProductList extends Observable {
    private List<String> productList=null;//产品列表
    private static ProductList instance;//唯一实例
    private ProductList(){}//私有化构造器

    /*
        取唯一实例--单例模式
     */
    public static ProductList getInstance(){
        if(instance==null){
            instance=new ProductList();
            instance.productList=new ArrayList<String>();

        }
        return instance;
    }

    /*
        观察者--电商接口
     */
    public void addProductListObserver(Observer ob){
        this.addObserver(ob);
    }
    /*
        新增产品--核心逻辑
     */
    public void addProduct(String newProduct){
        productList.add(newProduct);
        System.out.println("产品列表增加了新产品--"+newProduct);

        this.setChanged();//设置被观察对象发生了变化
        this.notifyObservers(newProduct);//通知观察者,并传递新产品参数
    }
}

电商接口类(观察者)代码如下:

/************************京东电商接口**************************************/
public class JDObserver implements Observer {
    @Override
    public void update(Observable o, Object product) {
        String newProduct =(String) product;
        System.out.println("上架新产品【"+newProduct+"】到京东jd.com");
    }
}

/*************************淘宝电商接口*************************************/
public class TaoBaoObserver implements Observer {
    @Override
    public void update(Observable o, Object product) {
        String newProduct =(String) product;
        System.out.println("上架新产品【"+newProduct+"】到淘宝taobao.com");
    }
}

测试代码如下:

    @Test
    public void test(){
        ProductList observable =ProductList.getInstance();
        
        TaoBaoObserver taoBao=new TaoBaoObserver();
        JDObserver jd=new JDObserver();
        //注册观察者
        observable.addObserver(jd);
        observable.addObserver(taoBao);
        //添加新商品
        observable.addProduct("2020全新商品S1");
    }

运行结果如下。这时,以后如要发布新商品,观察者就能自动触发上架的行为了,不会出现if语句的问题,拓展和维护更加方便。 

 

 

附:GOF23种设计模式的分类。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值