unified-message(统一消息平台),为业务系统提供了标准的消息发送功能

  • 支持发送短信、邮件、企业微信等消息,可以扩展支持其它的消息类型
  • 可以通过手机号、邮件、企业微信用户名直接发送, 可以直接通过用户名发送短信等

项目地址

gitee: https://gitee.com/wei772/unified-message

github: https://github.com/wei772/unified-message

使用方法

  • 运行项目

  • 调用发送消息接口

curl --location --request POST "http://localhost:8080/api/message/send" ^
--header "Content-Type: application/json" ^
--data-raw "{ \"channelName\":\"wecom\", \"content\":\"测试\", \"recipients\":[\"LiWei\"]}"

包结构和主要类介绍

  • domain包

    • 包含Message相关领域类
  • repository包
    • 访问数据存储相关类
    • 使用MongoDb存储数据
  • client包
    • 访问第三方服务
    • 使用原始feign访问第三方web接口
  • command包
    • 对应用户用例的实现
    • 使用标准的Command接口
  • controller包
    • 对外提供web接口访问
  • sender包
    • 实现发送Message相关类

整洁架构

来源 Robert C. Martin 的《架构整洁之道》,详情查看第22章 整洁架构

  • 业务实体,业务核心包含应用的业务对象

    • 包含domain包
  • 用例,通常包含特定应用场景的业务逻辑

    • 包含command包
  • 接口适配器,软件的接口适配器层中通常是一组数据转换器,它们负责将数据从对用例和业务实体而言最方便操作的格式,转化成外部系统(譬如数据库以及Web)最方便操作的格式。

    通常这一层的代码也会负责将数据从对业务实体与用例而言最方便操作的格式,转化为对所采用的持久性框架(譬如数据库)最方便的格式。

    • 包含 client 部分抽象和具体类,访问外部接口的网关
    • 包含 repository 的抽象类,比如MessageRepository,是一种数据库网关
    • 包含controller包,对外提供Web接口。接收和返回Web请求数据
  • 框架与驱动程序,最外层的模型一般是由数据库、Web 框架等组成的。

    • 包含client包下的实现类,比如Feign使用BlacktelSendService生成的请求类,对应外部接口
    • repository实现相关代码,比如MongoMessageRepository,对应数据库访问。
    • 包含Tomcat Web容器和Spring MVC等框架细节

测试驱动开发

本项目使用测试驱动开发的方法开发

复杂类的默认态与运行态

复杂类一般会依赖外部环境,在代码中体系依赖外部接口。这些外部接口可能也会依赖其它复杂对象。

在Java中IoC框架存在就是用来创建这些复杂类,使用起来十分方便

但是这样创建的类确难以进行单元测试

  • 单元测试不应该依赖任何复杂框架,太过笨重,也太过复杂
  • 严重影响单元测试的速度

为了兼容单元测试和实际运行的两种情况,我将类分成默认态与运行态的方式。这样保持了类的测试性,又保证了类的功能性

  • 使用默认构造函数生成默认状态,用于单元测试

    • 默认的实现可以依赖外部,也可以基于Mock依赖,主要看外部调用是否方便、稳定、代价是否合理,比如发送短信代价有点高必须Mock
  • 还有一个由main函数进行组装的,比如基于Spring IoC,用于运行环境的状态
    • 使用@Autowired注解指定构造函数,实现该功能

效果与感受

  • 流畅的组织所有开发活动的技术,测试驱动开发这种先写测试再开发的方式很流畅。

    • 不要绞尽脑汁再脑中、用文字还有图去思考设计,这种方法浪费时间,想象力也无法有效发挥。
    • 也不会一上来就编码,编写难以执行代码,代码基本没有设计,想到哪写到哪。
    • 使用单元测试可以持续重构,一直保持设计和编码变得更好的

测试驱动开发本质

下面一些经典数据的一些论述,涉及到测试驱动开发本质

《测试驱动开发 (Kent Beck) 》当中有几段话让我印象深刻,体现了这种方法的核心作用

  • 而我从书本上学到的却恰好相反:“编码为今天,设计为明天。”而测试驱动开发看起来已经彻底推翻了这一论点: **“为明天编码,为今天设计。”

    ** 。
  • 测试(Test)--自动、具体、切实的测试。按一个键就可以让测试运行。具有讽刺意味的是测试驱动开发不是一种测试技术(Cunningham

    Koan)。 它是一种分析技术、设计技术,更是一种组织所有开发活动的技术

《敏捷整洁之道:回归本源》关于复式记账的论述

  • 会计师们在1000年前发明了一条法则,并将其称为复式记账。每笔交易会写入账本两次:在一组账户中记一笔贷项,然后相应地在另一组账户中记为借项。

    这些账户最终汇总到收支平衡表文件中,用总资产减去总负债和权益。差额必须为零。如果不为零,肯定就出错了
  • 复式记账与TDD这两种纪律是等效的。它们都具有相同的功用:在极其重要的文档中避免错误,确保每个符号都正确。

    尽管编程对社会来说已经必不可少,

    但我们还没有用法律强制实施 TDD。可是,既然编写糟糕的软件已经造成了生命财产损失,立法还会远吗?

测试驱动开发步骤

首先编写任务清单,一般包含设计想法、要实现用例、重构任务等等,将TODO的事情要一个简单的文档记录,整个过程比较随意,有价值的想法就记录下来,完成之后将对应的任务划上删除线。

然后是具体编写过程

  1. 从任务清单中挑选任务,针对任务编写不通过的单元测试,包括无法编译和运行错误的用例
  2. 使单元测试运行通过
  3. 重构现有代码,使设计更佳。

每次写代码都重复这3个步骤,直到没有需要完成的任务。

其它测试经验

  • 单元测试相关代码也很重要

    • Mock代码挺重要,好的Mock代码能够尽可能模拟真实情况,减少gap
    • 执行单元测试的代码的重要性也不言而喻,是测试驱动开发的开始。
  • Disabled的单元测试

    • 基本都是运行代价比较大或者不稳定的的测试,通常是面向外部依赖。
    • 默认不执行测试,可以单独去执行的测试
  • 在单元测试注释记录异常

    • 在单元测试注释里记录曾经遇过的异常,以及分析还有解决方案,感觉很有趣。
    • 能记录一下曾经遇到过什么问题,并且怎么解决了,既有成就感,又可以有经验的积累和传播
  • 单元测试不能替代验收测试

    • 单元测试通过不保证基本功能正常
    • 但是能极大简化验收测试,一般是因为环境、IoC依赖等出现问题
    • 可以考虑用spring-test进行简单的验收测试

unified-message(统一消息平台)开源项目介绍的更多相关文章

  1. .NET平台开源项目速览(13)机器学习组件Accord.NET框架功能介绍

    Accord.NET Framework是在AForge.NET项目的基础上封装和进一步开发而来.因为AForge.NET更注重与一些底层和广度,而Accord.NET Framework更注重与机器 ...

  2. .NET平台开源项目速览(9)软件序列号生成组件SoftwareProtector介绍与使用

    在文章:这些.NET开源项目你知道吗?让.NET开源来得更加猛烈些吧!(第二辑)中,给大家初步介绍了一下Software Protector序列号生成组件.今天就通过一篇简单的文章来预览一下其强大的功 ...

  3. .NET平台开源项目速览(6)FluentValidation验证组件介绍与入门(一)

    在文章:这些.NET开源项目你知道吗?让.NET开源来得更加猛烈些吧!(第二辑)中,给大家初步介绍了一下FluentValidation验证组件.那里只是概述了一下,并没有对其使用和强大功能做深入研究 ...

  4. NET平台开源项目速览(6)FluentValidation验证组件介绍与入门(转载)

    原文地址:http://www.cnblogs.com/asxinyu/p/dotnet_Opensource_project_FluentValidation_1.html 阅读目录 1.基本介绍 ...

  5. .NET平台开源项目速览(1)SharpConfig配置文件读写组件

    在.NET平台日常开发中,读取配置文件是一个很常见的需求.以前都是使用System.Configuration.ConfigurationSettings来操作,这个说实话,搞起来比较费劲.不知道大家 ...

  6. .NET平台开源项目速览(12)哈希算法集合类库HashLib

    .NET的System.Security.Cryptography命名空间本身是提供加密服务,散列函数,对称与非对称加密算法等功能.实际上,大部分情况下已经满足了需求,而且.NET实现的都是目前国际上 ...

  7. .NET平台开源项目速览(10)FluentValidation验证组件深入使用(二)

    在上一篇文章:.NET平台开源项目速览(6)FluentValidation验证组件介绍与入门(一) 中,给大家初步介绍了一下FluentValidation验证组件的使用情况.文章从构建间的验证器开 ...

  8. .NET平台开源项目速览(2)Compare .NET Objects对象比较组件

    .NET平台开源项目速览今天介绍一款小巧强大的对象比较组件.可以更详细的获取2个对象的差别,并记录具体差别,比较过程和要求可以灵活配置. .NET开源目录:[目录]本博客其他.NET开源项目文章目录 ...

  9. .NET平台开源项目速览(17)FluentConsole让你的控制台酷起来

    从该系列的第一篇文章 .NET平台开源项目速览(1)SharpConfig配置文件读写组件 开始,不知不觉已经到第17篇了.每一次我们都是介绍一个小巧甚至微不足道的.NET平台的开源软件,或者学习,或 ...

  10. .NET平台开源项目速览(15)文档数据库RavenDB-介绍与初体验

    不知不觉,“.NET平台开源项目速览“系列文章已经15篇了,每一篇都非常受欢迎,可能技术水平不高,但足够入门了.虽然工作很忙,但还是会抽空把自己知道的,已经平时遇到的好的开源项目分享出来.今天就给大家 ...

随机推荐

  1. 微信小程序目录结构

    一.小程序框架 微信开放平台--小程序框架介绍 小程序的目录结构很清晰,主要由描述整体内容的app和描述具体页面的page组成.一般来说,习惯对小程序的目录结构进行更加清晰的规划,例如将程序种会用到的 ...

  2. Nuxt.js 应用中的 vite:extend 事件钩子详解

    title: Nuxt.js 应用中的 vite:extend 事件钩子详解 date: 2024/11/11 updated: 2024/11/11 author: cmdragon excerpt ...

  3. 告别繁琐的云平台开发!IoT_CLOUD之【百度云】

    ​ 众所周知,市面上有很多云平台,阿里云.腾讯云.中移OneNET.华为云.百度云.涂鸦云.Tlink云等等......并且每家云平台都有自己的协议,工程师要移植不同的SDK代码或基于各家的手册文档对 ...

  4. Mysql篇-语句执行计划详解(explain)

    概述 使用 explain 输出 SELECT 语句执行的详细信息,包括以下信息: 表的加载顺序 sql 的查询类型 可能用到哪些索引,实际上用到哪些索引 读取的行数 Explain 执行计划包含字段 ...

  5. rabbitmq-c与amqp扩展安装

    最近需要使用RabbitMQ进行消息队列处理 1.安装rabbitmq-c 在安装amqp之前需要先安装rabbitmq-c扩展 rabbitmq-c下载网址:https://github.com/a ...

  6. 1分钟学会如何提升PCIe通信速率,基于RK3568J + FPGA国产平台!

    测试数据汇总 表 1 PCIe总线介绍 PCIe,即PCI-Express(peripheral component interconnect express)是一种高速串行计算机扩展总线标准.主要用 ...

  7. SpringBoot+logback 日志打印脱敏,正常获取对象不受影响

    添加依赖 注意:springboot版本2.7.0 <dependency> <groupId>org.slf4j</groupId> <artifactId ...

  8. Qt 窗口随控件变换大小

    QVBoxLayout* verticalLayout = new QVBoxLayout(this); verticalLayout->setSizeConstraint(QLayout::S ...

  9. IOS多线程之NSOperation(3)

    IOS多线程之NSOperation(3) 操作优先级和服务质量 可以通过QueuePriority属性来设置operation在队列中的执行优先级 public enum QueuePriority ...

  10. Python 证件照换底色

    # -*- coding: utf-8 -*- ''' @Time : 2021/4/12 19:06 @Author : 水一RAR ''' import numpy as np import cv ...