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. vim粘贴文件格式不乱

    vim粘贴防止格式乱,配置以下命令然后在粘贴,即可~ :set paste

  2. DDCA —— 内存架构和子系统&存储器控制器

    1. 内存架构和子系统 1.1 如何控制访问? 访问控制: 存储单元的访问是通过 访问晶体管(access transistors) 进行控制的.访问晶体管像开关一样,可以连接或断开存储单元和位线(b ...

  3. 盘点Vue3 watch的一些关键时刻能够大显身手的功能

    前言 watch这个API大家应该都不陌生,在Vue3版本中给watch增加不少有用的功能,比如deep选项支持传入数字.pause.resume.stop方法.once选项.onCleanup函数. ...

  4. nginx之访问控制

    Nginx的源码提供了ngx_http_auth_basic_module这个模块,它可以来解决web访问认证的问题.这个模块是默认就编译进nginx的,可以直接拿来使用. ngx_http_auth ...

  5. js 计算过去和未来的时间距离现在多少天

    计算传入的任意一时间.计算出这个时间距离现在还有多少天!或者计算过去的时间距离现在已经过去了多少天! 返回值有两种! 1.负值 代表过去了多少天 2.正值 代表距离设定的时间还有多少天 说明:距离设定 ...

  6. 编译器-FIRST集合(补充:左递归)

    上一篇中实现的First函数没有考虑左递归,在这对此说明和实现 1.立即左递归 A -> Ab|a 1.两步或两步以上产生的左递归 A -> Bc|a B -> Ab|d 前面的实现 ...

  7. 二进制安装Kubernetes(k8s)v1.32.0

    二进制安装Kubernetes(k8s)v1.32.0 介绍 https://github.com/cby-chen/Kubernetes 开源不易,帮忙点个star,谢谢了 kubernetes(k ...

  8. docker创建Tomcat

    安装docker 查找tomcat docker search tomcat 下载镜像 docker pull tomcat 查看下载的镜像 docker images 运行Tomcat docker ...

  9. django目录结构、app概念和三板斧的初步介绍

    目录 一.django app(应用)的概念 概念 命令行创建应用 pycharm创建应用 创建应用注意事项 二.django主要目录结构 三.django小白必会三板斧 一.django app(应 ...

  10. 若依管理系统 -- 更换头像上传文件报错(/tmp/tomcat.8013579853364800617.8080/work/Tomcat/localhost/ROOT)

    一.错误情况 1.错误截图 二.错误解决情况 1.若依官方解答的链接 2.若依解答原文 1)原因: 在linux系统中,springboot应用服务再启动(java -jar 命令启动服务)的时候,会 ...