博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
观察者模式 -- 设计模式系列文章(二)
阅读量:4589 次
发布时间:2019-06-09

本文共 4209 字,大约阅读时间需要 14 分钟。

  • 概述

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

  • 定义

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

  • 个人理解

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

  • 示例介绍

  这里,我以电商系统中,比较常用的退货功能模块为例子来描述观察者模式。目前大多数电商平台都承诺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
observerList = new ArrayList
(); 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);    }}

 

 

 

转载于:https://www.cnblogs.com/rexfang/p/6702035.html

你可能感兴趣的文章
HDU 5934 Bomb(炸弹)
查看>>
领域驱动设计之聚合与聚合根实例一
查看>>
selenium中各个模块操作:下拉框、鼠标悬浮连贯、拼图拖拽操作
查看>>
C# 调用Windows图片查看器
查看>>
Excel系列教程(1):如何自动填充单元格
查看>>
jQuery中的冒泡事件和阻止冒泡
查看>>
pythonchallenge闯关 第13题
查看>>
linux上很方便的上传下载文件工具rz和sz使用介绍
查看>>
React之特点及常见用法
查看>>
【WEB前端经验之谈】时间一年半,或沉淀、或从零开始。
查看>>
优云软件助阵GOPS·2017全球运维大会北京站
查看>>
java23中设计模式只责任链模式
查看>>
linux 装mysql的方法和步骤
查看>>
poj3667(线段树区间合并&区间查询)
查看>>
51nod1241(连续上升子序列)
查看>>
SqlSerch 查找不到数据
查看>>
集合相关概念
查看>>
Memcache 统计分析!
查看>>
(Python第四天)字符串
查看>>
个人介绍
查看>>