jerry-promax

 

简历

  • DDD
    传统三层结构(MVC,Controller,Service,Mapper)是面向数据库开发,DDD(领域驱动设计)是面向业务开发,适用于业务复杂的时候,避免项目后期难以维护成上帝类(God Service)。
    DDD主要分成四层,适配层(负责接受接口请求)-> 应用层(流程编排,事务控制,调用领域对象)-> 领域层(核心) -> 基础设施层(MQ,DB,redis)
    简单来说就是把业务规则从service层搬到领域对象里,这样的话,就能让业务对象自己管理自己,不再依赖service替我去判断,更直观的,比如简历当中,减刑规则的话,A Service写一遍,B Service写一遍,C Service写一遍,而如果有一些改动比如积分之类的话,那每个service都要修改,而如果采用DDD的话,则只需要再领域对象当中修改即可。然后就是之前的疑问数据库的修改,他是有个repository接口,然后去写个实现类,这里面执行sql,这样设计还有个好处,就是如果换数据库的话,就不需要整个mapper都修改,只需修改实现类,即领域层不用改,这就是依赖倒置原则(DIP)。
传统写法
@Service
public class ReductionService {

    public void submit(Long id){

        Prisoner prisoner = mapper.selectById(id);

        if(prisoner.getScore() < 80){
            throw ...
        }

        if(prisoner.getYears() < 3){
            throw ...
        }

        if(prisoner.isViolation()){
            throw ...
        }

        prisoner.setStatus(APPLYING);

        mapper.update(prisoner);
    }

}
DDD代码
public class Prisoner {

    private Integer score;

    private Integer years;

    private Boolean violation;

    private Status status;

    public void applyReduction(){

        if(score < 80){
            throw ...
        }

        if(years < 3){
            throw ...
        }

        if(violation){
            throw ...
        }

        this.status = APPLYING;
    }

}
/**service类**/
@Transactional
public void submit(Long id){

    Prisoner prisoner =
        repository.findById(id);

    prisoner.applyReduction();

    repository.save(prisoner);
}
聚合根可以简单理解为一个业务对象的老大,聚合根和事务的区别是,聚合根是保证业务一致性,事务是保证数据一致性。

======================================================================================
Q1:你们项目为什么用 DDD?
R1:DDD 适合业务复杂的系统——像数据集成平台涉及十几个外部系统的数据同步,每个数据源的数据格式、业务含义都不同,需要领域建模来统一语言。反过来,如果只是简单的增删改查(比如若依的字典管理),用传统三层架构就够,上 DDD反而是杀鸡用牛刀。
Q2:介绍一下你们项目是怎么使用DDD
R2:项目采用 DDD 分层架构,将系统划分为接口层、应用层、领域层和基础设施层。应用层负责业务流程编排,领域层负责核心业务规则建模,基础设施层负责数据库访问和第三方接口调用。通过 DDD 将复杂业务逻辑从 Service 中抽离,降低模块耦合,提高系统可维护性和扩展性。我在项目中主要参与应用层和基础设施层开发,并学习了 DDD 在复杂业务系统中的落地实践。

  • XXL-Job
    xxl-job是一个分布式任务调度平台,Java原生定时任务 @Scheduled 的增强版。
普通定时任务
@Scheduled(cron = "0 0 1 * * ?")
public void syncData(){

}
这样会有一些问题,就比如多机器部署,然后每台都有定时任务的话,就会重复执行多次;如果任务失败怎么办;而且还不能动态修改时间,上面代码凌晨1点执行,现在改成2点,就得重启服务,修改代码。xxl-job就是为了解决这些。 基础架构就是俩个角色,调度中心负责管理任务,配置cron,失败重试,查看日志,监控报警。而执行器则是真正执行任务的。
XXL-Job示例代码
@XxlJob("syncPrisonerJob")
public ReturnT<String> sync(){

}
======================================================================================= ** 模拟 **

在某某科技有限公司担任Java后端开发实习生,主要参与智能减刑平台和数据集成平台两个项目开发。

在智能减刑平台中,我主要负责数据库国产化适配工作,将系统从 MySQL 迁移至达梦数据库,同时基于若依框架开发部分业务模块,并独立负责数据看板相关接口开发,与前端完成联调上线。

在数据集成平台中,我主要负责外部系统数据同步模块开发。项目采用 DDD 分层架构,将系统划分为多个业务域,通过 XXL-Job 定时调度同步任务,调用外部系统接口拉取数据,经过 DTO 转换映射后统一写入安防数据库,为前端数据看板提供数据支撑。

在实习过程中,对 DDD 架构设计、定时任务调度以及数据库国产化迁移有了一定实践经验。
这个项目在我参与的时候已经有雏形了,我是在上面加新的同步任务和修 bug。架构选 DDD的原因,我从实际开发体验来说主要有两点:第一,外部系统太多了——会见系统、电话系统、门禁系统、消费系统、点名系统等等,每个系统是不同厂商开发的,同一个"罪犯编号"在不同系统里的字段名都不一样,有的叫 prisoner_id,有的叫 F_CRIMINAL_NO,有的叫 ZFBH。DDD的做法是在领域层统一命名,每个数据域映射到一个独立的 domain 子包——比如 domain/prisoner/管罪犯信息、domain/phone/ 管电话记录。这样后续加新的数据源,比如智能床垫,直接新建一个 domain/zncd/包就行了,已有的十几个包完全不用动。第二,数据库种类多——源数据在达梦,目标库是瀚高,还有 MySQL 的遗留系统。Repository模式把接口定义在领域层,真正的 SQL 实现放在基础设施层的 DAO里。换数据库只需要在基础设施层替换实现,领域层的业务逻辑一行不用改。

posted on 2026-06-27 15:41  王的山而  阅读(9)  评论(0)    收藏  举报

导航