领域驱动设计学习(六)

102 阅读2分钟

「这是我参与2022首次更文挑战的第12天,活动详情查看:2022首次更文挑战image.png 上次看到了DDD中的实体和值对象,接下来看下DDD中的仓储的概念。

DDD中的仓储

上一篇文章我们说到DDD中将对象分为实体和值对象,实体对象用来执行业务规则,值对象用来传输数据。但是无论是哪种对象,在用户提交数据之后,应该有个地方去保存这些对象承载的数据,否则用户下次进来的时候就不能找到原先的数据了。争对这个情况,DDD抽象出了仓储的概念。顾名思义,仓储是用来存放东西的地方,在DDD里是用于存储用户所填写的数据。事实上,看到这,我们其实很熟悉,就是之前MVC模式里的Repository层。我们来看下面的代码:

class ServiceImpl implements Service {
    
    @Autowired
    Repository repository;
    
    public void update() {
        List<Object> updateData = repository.selectBySql("select * from xxx");
        ... // 各种更新
        repository.updateBySql("update xxx set xx = ?, xx2 = ? where id = ? ", updateData);
    }
    
}

上面的代码在DDD中其实是不推荐的,这是我们三层架构时期时常能看到的写法。sql作为数据访问,放到了Service层,这是不应该出现的。DDD里推荐的做法是将这些sql的和具体数据访问相关的代码放到repository层面去做,如下:

class ServiceImpl implements Service {
    
    @Autowired
    Repository repository;
    
    public void update() {
        // 这里不再出现sql的东西
        List<Object> updateData = repository.list();
        ... // 各种更新
        repository.updateList(updateData);
    }
    
}

上面的代码仅仅是将sql转移到了repository层去做了。这里可能会有人会有疑惑:这不是脱裤子放屁吗?如果不考虑其后的扩展问题,确实这样做没什么意义。如果我们的仓储访问一直都不会变,那么我们写代码确实爱怎么玩就怎么玩。但是如果涉及到数据迁移,仓储可以很好的将我们的代码划分在repository层,不需要对Service做任何改动。比如说我们要将数据从MySQL迁移到mongodb,或者是其它的数据库类型。我们只需要修改repository层的代码,而不需要修改原Service的代码。