观察者模式 -- 设计模式系列文章(二)

  • 概述

  在日常开发工作中,适当的使用一些设计模式,可以让代码扩展性更强,能更好地拥抱变化,让代码更加优雅。本文主要介绍设计模式中的观察者模式,并附上测试示例 Demo 供大家参考。

  • 定义

  观察者模式定义了对象之间一对多的依赖关系(一的一方为被观察者,多的一方为观察者),当被观察者状态发生变化时,所有的观察者能够及时收到通知,并做出相应的动作。

  • 个人理解

  观察者模式,主要应用在多个附属业务依赖主业务的场景,附属业务需要依赖主业务的执行结果,且主业务不需要等待附属业务的返回结果。通过观察者模式的应用,可以降低主业务与附属业务之间的耦合度,同时也提高了附属业务的可扩展性和灵活性,可根据实际情况,在运行时,动态追加附属业务或移除部分附属业务。

  • 示例介绍

  这里,我以电商系统中,比较常用的退货功能模块为例子来描述观察者模式。目前大多数电商平台都承诺7天无理由退货,在退货的过程中会涉及到很多业务逻辑的处理,比如资产退还(包括在线支付和平台资产)、积分扣减(购买商品获得积分)、修改库存,而平台资产又包含预存款、购物券、礼品卡等等。这里我们简单举例,以退还在线支付的金额和积分扣减为例。在整个主要的退货逻辑完成后,得到需要退还的金额和需要扣减的积分,把货款原路返还给用户,同时把购买商品时赠送的积分扣减,其中主要的退货逻辑就是主要业务,即被观察者,货款原路返还和积分扣减就是附属业务,即观察者。UML 图如下:

  从上面的 UML 图可以看出,被观察者需要实现 ISubject 接口,观察者需要实现 IObserver 接口。在被观察者对象中,用一个集合存放所有已经注册的观察者,并且通过 registerObserver 或 removeObserver 方法实现观察者的注册或移除,通过 notifyAllObserver 方法给所有已注册的观察者推消息。在观察者对象中,通过 register 和 remove 方法把观察者自己注册到被观察者或从被观察者中移除,通过 update 方法接收来自被观察者的消息,后续如果还需要处理其他的附属业务,只需要添加对应的观察者并注册到被观察者对象中即可,从而达到在运行时动态调整业务的效果。

  •  示例代码

   ISubject 被观察者接口(主业务接口)

package observer;

public interface ISubject {
    public void registerObserver(IObserver observer);
    public void removeObserver(IObserver observer);
    public void notifyAllObserver();
}

  IObserver 观察者接口(附属业务接口)

package observer;

public interface IObserver {
    public void update(String info);
    public void remove();
    public void register();
}

  ReturnOrder 被观察者实体类(主业务实体类)

package observer;

import java.util.ArrayList;
import java.util.List;

public class ReturnOrder implements ISubject {
    private List<IObserver> observerList = new ArrayList<IObserver>();

    public ReturnOrder() {
        // TODO Auto-generated constructor stub
    }

    @Override
    public void registerObserver(IObserver observer) {
        if(observerList.indexOf(observer)==-1){
            observerList.add(observer);
            System.out.println("添加观察者成功...");
        }
    }

    @Override
    public void removeObserver(IObserver observer) {
        int index = observerList.indexOf(observer);
        if(index>=0){
            observerList.remove(index);
            System.out.println("移除观察者成功...");
        }
    }

    @Override
    public void notifyAllObserver() {
        for(IObserver observer : observerList){
            observer.update("订单1001");
        }
    }
}

  IntegralObserver 观察者实体类(积分扣减业务实体类)

package observer;

public class IntegralObserver implements IObserver {
    private ISubject returnOrder;

    public IntegralObserver(ISubject returnOrder) {
        this.returnOrder = returnOrder;
    }

    @Override
    public void update(String info) {
        System.out.println(info + "扣减积分...");
    }

    @Override
    public void remove() {
        returnOrder.removeObserver(this);
    }

    @Override
    public void register() {
        returnOrder.registerObserver(this);
    }

    public ISubject getReturnOrder() {
        return returnOrder;
    }

    public void setReturnOrder(ISubject returnOrder) {
        this.returnOrder = returnOrder;
    }
}

  RefundObserver 观察者实体类(退款业务实体类)

package observer;

public class RefundObserver implements IObserver {
    private ISubject returnOrder;

    public RefundObserver(ISubject returnOrder) {
        this.returnOrder = returnOrder;
    }

    @Override
    public void update(String info) {
        System.out.println(info + "退还货款...");
    }

    @Override
    public void remove() {
        returnOrder.removeObserver(this);
    }

    @Override
    public void register() {
        returnOrder.registerObserver(this);
    }

    public ISubject getReturnOrder() {
        return returnOrder;
    }

    public void setReturnOrder(ISubject returnOrder) {
        this.returnOrder = returnOrder;
    }
}

  TestMain 测试类

package test;

import observer.IntegralObserver;
import observer.RefundObserver;
import observer.ReturnOrder;

public class TestMain {

    public static void main(String[] args) {
        ReturnOrder returnOrder = new ReturnOrder();
        IntegralObserver integralObserver = new IntegralObserver(returnOrder);
        integralObserver.register();
        RefundObserver refundObserver = new RefundObserver(returnOrder);
        refundObserver.register();

        returnOrder.notifyAllObserver();
        returnOrder.removeObserver(refundObserver);
        returnOrder.registerObserver(refundObserver);
    }

}

 

欢迎转载,转载必须标明出处 

 

posted on 2017-04-13 08:47  RexFang  阅读(432)  评论(0编辑  收藏  举报

导航