《设计模式就该这样学》之使用桥接模式设计复杂的消息系统

本文节选自《设计模式就该这样学》

举个例子,我们在平时办公的时候经常通过邮件消息、短信消息或者系统内消息与同事进行沟通。尤其在走一些审批流程的时候,我们需要记录这些过程以备查。根据类型来划分,消息可以分为邮件消息、短信消息和系统内消息。但是,根据紧急程度来划分,消息可以分为普通消息、加急消息和特急消息。显然,整个消息系统可以划分为两个维度,如下图所示。

图片

如果我们用继承,则情况就复杂了,而且也不利于扩展。邮件消息可以是普通的,也可以是加急的;短信消息可以是普通的,也可以是加急的。下面我们用桥接模式来解决这个问题。首先创建一个IMessage接口担任桥接的角色。

/**
 * 实现消息发送的统一接口
 */
public interface IMessage {
    //要发送的消息的内容和接收人
    void send(String message, String toUser);
}

创建邮件消息实现EmailMessage类。

/**
 * 邮件消息的实现类
 */
public class EmailMessage implements IMessage {
    public void send(String message, String toUser) {
        System.out.println("使用邮件消息发送" + message + "给" + toUser);
    }
}

创建短信消息实现SmsMessage类。

/**
 * 短信消息的实现类
 * SMS(Short IMessage Service)短信消息服务
 */
public class SmsMessage implements IMessage {
    public void send(String message, String toUser) {
        System.out.println("使用短信消息发送" + message + "给" + toUser);
    }
}

然后创建桥接抽象角色AbstractMessage类。

/**
 * 抽象消息类
 */
public abstract class AbstractMessage {
    //持有一个实现部分的对象
    IMessage message;

    //构造方法,传入实现部分的对象
    public AbstractMessage(IMessage message) {
        this.message = message;
    }

    //发送消息,委派给实现部分的方法
    public void sendMessage(String message, String toUser) {
        this.message.send(message, toUser);
    }
}

创建具体实现普通消息NomalMessage类。

/**
 * 普通消息类
 */
public class NomalMessage extends AbstractMessage {

    //构造方法,传入实现部分的对象
    public NomalMessage(IMessage message) {
        super(message);
    }

    @Override
    public void sendMessage(String message, String toUser) {
        //对于普通消息,直接调用父类方法发送消息即可
        super.sendMessage(message, toUser);
    }
}

创建具体实现加急消息UrgencyMessage类。

/**
 * 加急消息类
 */
public class UrgencyMessage extends AbstractMessage {

    //构造方法
    public UrgencyMessage(IMessage message) {
        super(message);
    }

    @Override
    public void sendMessage(String message, String toUser) {
        message = "加急:" + message;
        super.sendMessage(message, toUser);
    }

    //扩展它功能,监控某个消息的处理状态
    public Object watch(String messageId) {
        //根据给出的消息编码(messageId)查询消息的处理状态
        //组织成监控的处理状态,然后返回
        return null;
    }
}

最后编写客户端测试代码。

 public static void main(String[] args) {
        IMessage message = new SmsMessage();
        AbstractMessage abstractMessage = new NomalMessage(message);
        abstractMessage.sendMessage("加班申请速批", "王总");

        message = new EmailMessage();
        abstractMessage = new UrgencyMessage(message);
        abstractMessage.sendMessage("加班申请速批", "王总");
}

运行结果如下图所示。

图片

在上面的案例中,我们采用桥接模式解耦了“消息类型”和“消息紧急程度”这两个独立变化的维度。后续如果有更多的消息类型,比如微信、钉钉等,则直接新建一个类继承IMessage即可;如果紧急程度需要新增,则同样只需新建一个类实现AbstractMessage类即可。

设计模式系列文:

《设计模式就该这样学》之趣谈装饰器模式,让你一辈子不会忘

看了这篇文章后,面试官再也不敢问你非结构化存储的原理了

吹爆阿里P8的SQL优化笔记,由于太全直接被GitHub下架

《设计模式就该这样学》之使用策略模式重构电商折扣和支付场景

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Design Patterns: Elements of Reusable Object-Oriented Software(以下简称《设计模式》),一书由Erich Gamma、Richard Helm、Ralph Johnson和John Vlissides合著(Addison-Wesley,1995)。这四位作者常被称为“四人组(Gang of Four)”,而这本书也就被称为“四人组(或 GoF)”书。他们首次给我们总结出一套软件开发可以反复使用的经验,帮助我们提高代码的可重用性、系统的可维护性等,解决软件开发中的复杂问题。设计模式已诞生20多年,其间相继出版的关于设计模式的经典著作不计其数。如果说GoF的《设计模式》是设计模式领域的“圣经”,那么之后出版的各种关于设计模式的书籍可称为“圣经”的“批注版”或者“白话版”。本书正是基于GoF的《设计模式》来编写的。  本课程由《设计模式就该这样》作者亲授,课程内容和书籍完全同步,可以作为作者对“圣经”实践的精华总结,是一门可以真正能够落地的“设计模式”的课程,也是目前全网唯一一门结合框架源码如何落地“设计模式”这个角度来理解设计模式的课程。本课程将结合JDK、Spring、MyBatis、Tomcat、Netty等经典框架源码展开对设计模式的分析。当然,本课程中还会结合作者多年的“踩坑填坑”经验和“教答疑”经验,用比“圣经”更深刻、更全面、更通俗、更生动、更有趣、更接地气的方式并且结合真实业务场景分析每种设计模式的优缺点,治愈“设计模式选择困难症”。选设计模式就像相亲选对象,一旦做好了接受TA缺点的准备,那TA就一定属于你。所以,本课程内容对于日常开发而言更具有指导意义。内容均从实战角度出发,在日常应用中,设计模式从来都不是单个设计模式独立使用的。在实际应用中,通常多个设计模式混合使用,你中有我,我中有你。下图完整地描述了设计模式之间的混用关系,希望对大家有所帮助。在《设计模式就该这样》一书中,还有大量的UML图及易混淆的设计模式对比案例分析,也欢迎大家关注。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值