乐趣区

关于微服务:程序员日记当微服务遇到了电饼铛

作者:京东物流 赵勇萍

之后的日子里,我可能会陆陆续续写一写跟编程技术感悟相干的文章,一来能够梳理一下对技术和工作的思考,二来也能够记录一下技术成长的的过程。

换个叫法的话,就叫做程序员日记吧。

电饼铛

明天就从电饼铛说起。

上周,我家的电饼铛坏了,起因可能是荡涤过后线路短路导致的。那个老式电饼铛的确用了好些年,且性能繁多,基本上除了开要害,再也没有什么能够按钮的中央了,不过老妈却始终用的很棘手。

而对我来说,这的确个好消息,终于能够换一个好电饼铛了。于是在网上买了一个七百多的苏泊尔的电饼铛,这一下子感觉高大上了许多,很多内置模式,能够反对煎蛋,煎饼,炸鸡翅等多种模式,对温控的把握也非常精准。

不过,对于我老妈来说,她并没有显得多兴奋,我将应用阐明一一教给她用,但老妈最终只抉择一种用法:关上开关,抉择自定义模式,所有都靠教训去判断电饼铛的温度和对食材的感觉,其余所有的内置模式,对她老人家来说,如同的确是多余的。

对此,我有点陷入深思,总感觉有一种似曾相识的感觉。认真思考,其实这种状况在编程过程中不足为奇。其实这不就是咱们微服务架构中常常会遇到的一种状况么 ….

好的,接下来,如果把我和我老妈的上述行为形象为代码,能够写成如下:

老妈做煎蛋:

/**
 * 老妈做煎鸡蛋
 */
public class MainApplicaiton{
    /**
     * 电饼铛
     */
    @Resource
    private DianBingCheng dianBingCheng;
    /**
     * 老妈的判断服务类
     */
    @Resource
    private MotherCheckService matherCheckService;
    /**
     * 老妈的行为服务 
     */

    private MotherBehaviorService MotherBehaviorService;

    public void execute() {
        // 关上电饼铛
        MotherBehaviorService.Open(dianBingCheng);
        // 查看温度
        matherCheckService.CheckTemperature(dianBingChengAggregate);
        // 开始煎鸡蛋
        MotherBehaviorService.fryEggs();
        // 查看是否熟了
        matherCheckService.CheckRipe();// 实现,关机盛盘
        matherService.complete();}
}

我做煎蛋:

public class MainApplicaiton {
    /**
     * 电饼铛聚合根
     */
     @Resource
     private DianBingChengAggregateRoot dianBingChengAggregate;

     public void execute() {
        // 开机
        dianBingChengAggregate.open();
        // 煎蛋模式
        dianBingChengAggregate.fryEggs();
        // 实现,关机盛盘
        dianBingChengAggregate.complete();}
}

大家能够看出这两者的实现区别,咱们有时候须要思考一下,我不就是解决一个日常特地简略的事件,肯定要引入那么多的服务类么?

贫血模型和充血模型

可能大家感觉进去了,这两种实现,就是畛域驱动设计中典型的贫血模式和充血模式。这里不得不先说一下贫血模型和充血模型。

贫血模型是事务脚本模式。对于程序员来说,脚本呢必定是要比写设计说明书要快的多了。比方,咱们要设计一个订单流程,包含下单,勾销,售后,拆单等状况下的订单流转,那么咱们就就会任选一个 Service 类,写一个办法就能搞定,而这时,原来的那个 order 类中,就会十分十分的“清新”,外面全是 GET 办法和 Set 办法,没有任何行为。而很多人喜爱给这个 order 类一个定义,叫 OrderDomain,订单畛域模型。当然我更喜爱叫这种模型为 DB 模型,是面向数据库的,而不是面向畛域业务的。

而充血模型是才是典型的畛域模型模式 。他实现起来绝对简单,但这种简单也是绝对的,还是下面的例子,咱们会在 Order 这个对象中放入响应的动作行为的办法,例如咱们更新订单状态不会用 setStatus()这种办法,而会封装相似 orderCancel(),orderComplete() 的这种业务行为办法,当然这种形式会让这个类略显“简单”。

总结一句话,真正的畛域模型会把数据和行为聚合在一起,造成聚合根,对外提供基于行为的办法,而非脚本化的增删改查。只有这样才可能更好的对微服务进行拆分。

如果仅是贫血模型其实不是对系统架构危害最大的,想咱们曾经很相熟的 MVC,通过贫血模型也能够写出简单的高效快捷的零碎。

然而,有一种危害就会很大了:

就像好多同学用这面向对象的语言,写着面向过程的代码一样,很多同学喜爱用冠以畛域驱动设计的噱头,却写着 MVC 式的“面向数据库编程”,它最大的问题是你引入了畛域模型设计的所有老本,但却没有带来任何一丝的收益

只有当你充沛应用了面向对象设计来组织简单业务逻辑之后,能力对消这种老本。如果将所有行为都写入一个一个的 Service 类,畛域是被割裂的,那最终你会失去一组事务处理脚本,从而错过了畛域模型带来的益处,而且当业务足够简单时,你将会失去一堆爆炸的事务处理脚本。

此外,你还会发现,

原本属于一个畛域的能力,却被散落在了工程的各个角落。这样一来,根本无法造成一个可复用的能力。

当然有同学也会提出疑难:“_我的业务场景中畛域之间其实关系比拟严密,我会常常遇到会触发同时跟不同畛域行为相干的业务,在这种状况下,我就通过一个个的 Service 扩大,这就是一种不言而喻的解决方案呀~~_”

其实有这种想法的同学,次要是对畛域驱动设计了解不粗浅的,同时又对传统的 MVC 框架开发积重难返。

其实畛域驱动设计早已给出它的最佳实际,那就是畛域事件。而面向事件的编程思维对于后端来说,是一种十分高效和优良的思维。通过畛域事件,咱们能够实现畛域之间的解耦,同时也保护了畛域模型的独立性和数据一致性。而对于畛域事件又是一个很大的话题,当前有机会再聊。

思考

在咱们每个人的大脑里,对于一件事,如果没有概念和了解的话,咱们会无意识的规避那件事,或者用本人相熟的概念去套用。微服务,DDD,中台这些词汇,恰好是这样的概念。这是有了这些概念,才让咱们一直的致力去学习它,思考他,钻研他。

在微服务和 DDD 这波浪潮里,很多同学都想用这些概念来包装本人,就像我面试过的很多候选者,他们中的很多都在简历中写了精通畛域驱动设计,同时也能说出一些聚合根,实体,值对象等概念,然而理论落地就变成了贫血模式的代码。

所以,对于程序员来说,最外围的能力并不是你会几种语言,会几个架构或者几个名词概念,而是了解那些概念并转化成本人的编程思维。

同时,

勇于创新和敢于颠覆本人的已有认知,也是一名程序员是否有始终后退的能源的前提

退出移动版