alibaba/cola架构中的Gateway层的代码腐败问题

一、概述

cola架构作为整洁面向对象的分层架构,从战略设计到业务设计,都提供了不错的方法论,并提供了可以落地的领域驱动设计方案。

在学习与使用cola架构的过程中,对cola架构中的Gateway层腐败问题做出问题的发现、分析、解决、总结.
cola架构:https://github.com/alibaba/COLA

二、问题描述

在提出问题之前,先引用自cola源码中的一段代码

public List<SubMetric> listByTechInfluence(String userId){
    List<MetricDO> metricDOList = metricMapper.listByMainMetric(userId, MainMetricType.TECH_INFLUENCE.getMetricCode());
    ATAMetric ataMetric = new ATAMetric();
    SharingMetric sharingMetric = new SharingMetric();
    PatentMetric patentMetric = new PatentMetric();
    PaperMetric paperMetric = new PaperMetric();
    List<SubMetric> subMetricList = new ArrayList<>();
    subMetricList.add(ataMetric);
    subMetricList.add(sharingMetric);
    subMetricList.add(patentMetric);
    subMetricList.add(paperMetric);
    metricDOList.forEach(metricDO -> {
        String json = metricDO.getMetricItem();
        switch (SubMetricType.valueOf(metricDO.getSubMetric())){
            case ATA:
                ataMetric.addMetricItem(ATAMetricItem.valueOf(json));
                break;
            case Sharing:
                sharingMetric.addMetricItem(SharingMetricItem.valueOf(json));
                break;
            case Patent:
                patentMetric.addMetricItem(PatentMetricItem.valueOf(json));
                break;
            case Paper:
                paperMetric.addMetricItem(PaperMetricItem.valueOf(json));
            default:
                log.error("illegal SubMetric type: " + metricDO.getSubMetric());
        }
    });
    return subMetricList;
}

上面是MetricGatewayImpl 类中的listByTechInfluence方法

针对这段代码,我们提出假设:

1.SubMetricType 中的文章类型,出现了需要增加的情况,是否意味着,此方法是否需要继续膨胀?

2.SubMetricType是用户文章的一种属性,那么,当文章属性变多时,比如,增加属性“文章字数、文档版本、文章点赞数、分享数、收藏数、是否在国家期刊发表”等,根据不同属性计算出的分数不同。 按领域对象设计,需要针对属性进行建模,那么,按照原有设计,都需要在gateway层将持久化对象转换为领域对象,那么gateway层将不堪重负。

基于以上两个假设,提出问题:

  1. 如何实现领域对象的持久化?并在实施的过程中解决基础设施层腐败问题?
  2. Gateway层的职责应如何设计?

三、问题分析

1.引用《领域驱动设计》这本书中的部分观点:

上述文字中,提到,整个AGGREGATE通常由一个独立的FACTORY来创建,FACTORY负责把对根的引用传递出去,并确保创建出的AGGREGATE满足固定规则。

按照上述观点,聚合根通常由工厂来创建,那么在cola架构中,领域对象的创建实在Gateway层中实现的。

那么如果说,将领域对象的创建工作有对象工厂实现,那么需要解决另一个问题,持久化对象与对象工厂之间如何建立关系?

2.引用《领域驱动设计》这本书中的部分观点

按照上述观点,使用值对象来优化数据库,那么,如果为聚合根,创建一个值对象,用于与计算机底层进行交互,那么,Gateway层的问题就迎刃而解。

四、解决方案

概述:做厚领域对象层,做薄Gateway层

1.在领域对象层使用值对象和对象工厂,做厚领域对象层

        值对象valueObject职责:用于所有能够存储聚合根值的信息

        对象工厂factory职责:用于值对象和聚合根之间的桥梁,用于使用值对象创建聚合根或者由聚合根创建值对象。

在领域层创建聚合根的值对象,使用工厂对象作为聚合更与值对象之间的桥梁,将聚合根与值对象之间的转换关系沉淀于工厂对象中。

在此逻辑中,工厂对象可以在进行拆分更细粒度的工厂对象,那么如上述cola中,文章的属性扩展引发Gateway层膨胀的问题迎刃而解。

2.做薄Gateway层

由于对象的创建逻辑交给了对象工厂,那么Gateway层职责就变得简单了。

        Gateway职责: 负责操作持久化层,并将持久化对象转换为领域对象中的值对象,

在java中,对象之间的拷贝,有mapstruct、Apache.BeanUtils.copyProperties()、SpringFrameWork下的BeanUtils.copyProperties()等诸多方案。如上述框架任然不能满足需求,那么在项目中考虑单独引入converter层作为持久层对象po与值对象之间的转换关系。

五、总结

按照以上方法,既保留了领域对象的扩展能力,同时解决了基础设施层的腐败问题。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值