DDD分层架构

2022-02-11  本文已影响0人  zh_harry

一个好的架构

DDD整洁架构实践

https://gitpod.io/workspaces

https://github.com/Sairyss/domain-driven-hexagon

六边形架构与洋葱架构其中心思想类似

image

纵向DGA架构设计

image

基础框架设计

image

DDD

战略设计

/* The DDD Cargo sample application modeled in CML. Note that we split the application into multiple bounded contexts. */
ContextMap AdIndexMap {
    
    contains AdIndexContext,GoodsContext,SellerContext,StockContext,PromotionContext,AddressCenterContext
    contains StationContext,BatchStockContext,ForcastSalesVolumeContext,RecallContext,MergeContext,RecommendContext
    contains GoodsTeam,StockPlanTeam,SupplyDemandTeam,PromotionTeam,ShareBusinessTerm,StationTerm,SearchRecommendTerm
    AdIndexContext [D,ACL]<-[U,OHS,PL] GoodsContext
    AdIndexContext [D,ACL]<-[U,OHS,PL] GoodsContext
    AdIndexContext [D,ACL]<-[U,OHS,PL] SellerContext
    AdIndexContext [D,ACL]<-[U,OHS,PL] StockContext
    AdIndexContext [D,ACL]<-[U,OHS,PL] PromotionContext
    AdIndexContext [D,ACL]<-[U,OHS,PL] AddressCenterContext
    AdIndexContext [D,ACL]<-[U,OHS,PL] StationContext
    AdIndexContext [D,ACL]<-[U,OHS,PL] BatchStockContext
    AdIndexContext [D,ACL]<-[U,OHS,PL] ForcastSalesVolumeContext
    MergeContext [C]<-[S] AdIndexContext
    MergeContext [P] <-> [P] RecallContext
    RecommendContext [D] <- [OHS,PL] MergeContext
    RecommendContext [SK] <-> [SK] MergeContext


    //GoodsTeam[U,S]->[D,C]SupplyDemandTeam
    //StockPlanTeam[U,S]->[D,C]SupplyDemandTeam
    //PromotionTeam[U,S]->[D,C]SupplyDemandTeam
    //ShareBusinessTerm[U,S]->[D,C]SupplyDemandTeam
    //StationTerm[U,S]->[D,C]SupplyDemandTeam
    //SupplyDemandTeam[U,S]->[D,C]SearchRecommendTerm
}

BoundedContext AdIndexContext implements AdIndexDomain
BoundedContext GoodsContext implements GoodsDemain
BoundedContext SellerContext implements SellerDomain
BoundedContext StockContext implements StockDomain
BoundedContext PromotionContext implements PromotionDomain
BoundedContext AddressCenterContext implements AddressCenterDomain
BoundedContext StationContext implements StationDomain
BoundedContext BatchStockContext implements BatchStockDomain
BoundedContext ForcastSalesVolumeContext implements ForcastSalesVolumeDomain
BoundedContext RecallContext implements RecallDomain
BoundedContext MergeContext implements MergeDomain
BoundedContext RecommendContext


/* Team Definitions */
BoundedContext GoodsTeam  realizes GoodsContext, SellerContext{
    type = TEAM
    domainVisionStatement = "供应链 商品研发分组."
}

BoundedContext StockPlanTeam  realizes StockContext, BatchStockContext{
    type = TEAM
    domainVisionStatement = "供应链 库存计划."
}

BoundedContext SupplyDemandTeam  realizes ForcastSalesVolumeContext, AdIndexContext,MergeContext,RecallContext{
    type = TEAM
    domainVisionStatement = "供应链 供需决策."
}

BoundedContext PromotionTeam  realizes PromotionContext{
    type = TEAM
    domainVisionStatement = "营销研发组-用户研发分组."
}

BoundedContext ShareBusinessTerm  realizes AddressCenterContext{
    type = TEAM
    domainVisionStatement = "技术中台组-共享服务分组"
}

BoundedContext StationTerm  realizes StationContext{
    type = TEAM
    domainVisionStatement = "履约研发组-门店研发分组"
}

BoundedContext SearchRecommendTerm  realizes RecommendContext{
    type = TEAM
    domainVisionStatement = "搜索推荐"
}




Domain AdDomain {
    Subdomain MergeDomain {
        type = CORE_DOMAIN
        domainVisionStatement = "广告mergeRerank核心子域"
    }
    Subdomain RecallDomain {
        type = SUPPORTING_DOMAIN
        domainVisionStatement = "召回支撑域."
    }
    Subdomain AdIndexDomain {
        type = SUPPORTING_DOMAIN
        domainVisionStatement = "索引支撑域."
    }
}

Domain AdIndexDomain {
    Subdomain IndexDomain {
        type = CORE_DOMAIN
        domainVisionStatement = "广告索引核心子域"
    }
    Subdomain GoodsDemain {
        type = SUPPORTING_DOMAIN
        domainVisionStatement = "商品支撑域."
    }
    Subdomain SellerDomain {
        type = SUPPORTING_DOMAIN
        domainVisionStatement = "卖家支撑域."
    }
    Subdomain StockDomain {
        type = SUPPORTING_DOMAIN
        domainVisionStatement = "库存支撑域."
    }
    Subdomain AddressCenterDomain {
        type = SUPPORTING_DOMAIN
        domainVisionStatement = "基础地址支撑域."
    }
    Subdomain StationDomain {
        type = SUPPORTING_DOMAIN
        domainVisionStatement = "门店支撑域."
    }
    Subdomain PromotionDomain {
        type = SUPPORTING_DOMAIN
        domainVisionStatement = "促销支撑域."
    }

    Subdomain BatchStockDomain {
        type = SUPPORTING_DOMAIN
        domainVisionStatement = "批次库存支撑域."
    }
    Subdomain ForcastSalesVolumeDomain {
        type = SUPPORTING_DOMAIN
        domainVisionStatement = "预估销量支撑域."
    }
}

image

战术设计

/* The original booking application context */

BoundedContext AdMergeRerankContext {
    Module ad {
        /**
         * 
         * {com.公司名.组织架构.业务.上下文.*},这样的组织结构能够明确的将一个上下文限定在包的内部。
         * import com.company.team.bussiness.lottery.*;//抽奖上下文
         * import com.company.team.bussiness.riskcontrol.*;//风控上下文
         * import com.company.team.bussiness.counter.*;//计数上下文
         * import com.company.team.bussiness.condition.*;//活动准入上下文
         * import com.company.team.bussiness.stock.*;//库存上下文

         * import com.company.team.bussiness.lottery.domain.valobj.*;//领域对象-值对象
         * import com.company.team.bussiness.lottery.domain.entity.*;//领域对象-实体
         * import com.company.team.bussiness.lottery.domain.aggregate.*;//领域对象-聚合根
         * import com.company.team.bussiness.lottery.service.*;//领域服务
         * import com.company.team.bussiness.lottery.repo.*;//领域资源库
         * import com.company.team.bussiness.lottery.facade.*;//领域防腐层
         * 
         */
        basePackage = com.company.team.bussiness.ad.merge.rerank.domain
        
        Entity RecoBean {
                 /**
                * sku id .
                */
                Integer skuId;
                /**
                * sku name.
                */
                Integer skuName;
            }
            ValueObject SkuPosition {
                Integer position
                - RecoBean recoBean
            }

            ValueObject PositionSpecification{
                - List<SkuPosition> fixedPositionMap
                 /**
                * 原始列表的售罄标记
                */
                String originSoldOutMark;
                - List<RecoBean> soldOutRecoBeanList 

                def void isSatisfiedBy(List<@RecoBean> mergeResult);
            }

            ValueObject SkuPositionMarker {
                - PositionSpecification positionSpecification
                - List<RecoBean> inclinableRecoBeanList
                - List<SkuEntity> inclinableAdList
            }

            ValueObject ScoreStrategy {
                def double score(SkuEntity SkuEntity);
            }

        Aggregate SkuAggregation {
            Entity SkuEntity {
                aggregateRoot
                /**
                 * sku id
                 */
                SkuId skuId
                Integer originPosition;
                Boolean isIncline;
                Integer rerankPosition;
                Double score;
                Double originScore;
                Boolean isAd;
                Boolean isRecommend;
                - Price price
                - Category category
                - ShelfLife shelfLife
                - Promotion promotion
                - Stock stock
                - BasicInfo basicInfo
                Repository SkuRepository {
                    List<@SkuEntity> findAll(String recallKey);
                }
            }
            ValueObject Price {
                /**
                 * 会员价 .
                 */
                Integer price;
                /**
                 * VIP价.
                 */
                Integer vipPrice;
                /**
                 * 成本价.
                 */
                Integer costPrice;

                def double score(double originScore);
            }
            ValueObject Category {
                /**
                 * 后台一级品类.
                 */
                Integer firstCid;
                /**
                 * 后台二级品类.
                 */
                Integer secondCid;
                /**
                 * 后台三级品类.
                 */
                Integer thirdCid;
                /**
                 * 后台一级品类名称.
                 */
                String firstCname;
                /**
                 * 后台二级品类名称.
                 */
                String secondCname;
                /**
                 * 后台三级品类名称.
                 */
                String thirdCname;
                /**
                 * 前台一级类目ID.
                 */
                Set<Integer> frontFirstCidSet;
                /**
                 * 前台二级类目ID.
                 */
                Set<Integer> frontSecondCidSet;
                /**
                 * 前台一级类目名称.
                 */
                Set<String> frontFirstCnameSet;
                /**
                 * 前台二级类目名称.
                 */
                Set<String> frontSecondCnameSet;

                def double score(double originScore);

            }
            ValueObject ShelfLife {
                /**
                 * 总货架期(天).
                 */
                Integer totalShelfLife;
                /**
                 * 允收期(小时).
                 */
                Integer allowReceiveShelfLife;
                /**
                 * 微仓最小货架期.
                 */
                Integer microWarehouseMinShelfLife;
                /**
                 * 大仓货架期.
                 */
                Integer bigWarehouseShelfLife;
                /**
                 * 周围规则.
                 */
                Integer turnoverRule;
                /**
                 * 超效期周转倍数
                 */
                private Double overExpiryMulti;
                private Double otherOverExpiryMulti;

                def double score(double originScore);

            }
            ValueObject Promotion {
                /**
                 * 促销开始时间
                 */
                Long startPromotionTime;
                /**
                 * 促销结束时间
                 */
                Long endPromotionTime;
                /**
                 * 促销类型
                 */
                Integer promotionType;
                /**
                 * 促销场景
                 */
                Integer promotionScene;

                def double score(double originScore);

            }
            ValueObject Stock {
                /**
                 * 库存.
                 */
                Integer stock;
                /**
                 * 批次库存
                 */
                List<BatchStockBO> batchStocks;
                /**
                 * 总批次库存
                 */
                Integer batchStockWarning;
                /**
                 * 临期报损库存
                 */
                Integer warningStock;

                def double score(double originScore);

            }
            ValueObject BasicInfo {
                /**
                 * sku名称.
                 */
                String skuName;
                /**
                 * 商品上下架状态 2上架,3预下架,4预上架.
                 */
                Integer skuStatus;
                /**
                 * sku类型 默认为0 1原料商品,2普通商品,3虚拟组套,4虚拟商品.
                 */
                Integer skuType;
                /**
                 * 商品类型 默认为0 1原料商品,2普通商品,3虚拟组套,4虚拟商品.
                 */
                Integer itemType;
                /**
                 * 业态 (卖家类型,一个SKU只有一个卖家类型).
                 */
                Integer sellerType;
                /**
                 * 是否预售 1为预售品,0为否.
                 */
                Integer isPresale;
                Long sellerId;

                def double score(double score);
            }

            Service MergeRankService {
        
                @SkuPositionMarker fixedPositionPrepare(List<@RecoBean> originRecoList,List<@SkuEntity> adSkuEntities,Set<String> batchSkuSet);

                @SkuPositionMarker allInclinablePrepare(List<@RecoBean> originRecoList,List<@SkuEntity> adSkuEntities,Set<String> batchSkuSet);

                void rank(List<@SkuEntity> adEntries,@ScoreStrategy scoreStrategy);

                List<@RecoBean> merge(@SkuPositionMarker skuPositionMarker,List<@SkuEntity> adEntries);

                List<@RecoBean> merge(@SkuPositionMarker skuPositionMarker,List<@SkuEntity> adEntries,List<Integer> positions);

                List<@RecoBean> shuffler(@SkuPositionMarker skuPositionMarker,List<@RecoBean> sortedResult);

                Boolean mergeValid(@SkuPositionMarker skuPositionMarker,List<@RecoBean> sortedResult);

            }
        }
    }
}


image.png
#http://bj.91join.com/color.html 

digraph G1 {
    rankdir=TB;
    graph [compound=true]
    node [color=black,shape=egg fillcolor="#FFFFFF" style="filled" shape=egg fontcolor="#000000"] //All nodes will this shape and colour
    edge [color=black] //All the lines look like this

    subgraph cluster_basic {
        fillcolor="#FFAB00" 
        fontcolor="white"
        style="filled"
        label = "Infrastructure Layer";

        SpringBoot[shape=egg]
        Dubbo[shape=egg]
        #_[color="white" fontcolor="#ffffff"]
        ElasticSearchRepositories[shape=egg]
        RedisRepositories[shape=egg]
        "Data_Mapper DO<->PO"
    };

    subgraph cluster_domain {
        fillcolor="#01939A" 
        style="filled"
        fontcolor="white"
        label = "Domain Layer"
        Repository_API[shape=egg]
          subgraph cluster_ddd{
                Entity[shape=egg]
                Value_Object[shape=egg]
                Domain_Service[shape=egg]
                Aggregation[shape=egg]
                label = "Domain DDD"

          }
    };

    subgraph cluster_protocol{
        fillcolor="#9FEE00" 
        fontcolor="white"
        style="filled"
        label = "Protocol Layer"
        DTO RpcAPI
    }

    subgraph cluster_app{
        fillcolor="#9FEE00" 
        fontcolor="white"
        style="filled"
        label = "Application Layer"
        DTO_Assemble
        Adapters
            subgraph cluster_service{
            {
                rank="same";Valid;Shuffler;Merge;ReRank;Rank;Filter;Recall;}
                Recall->Filter->Rank->ReRank->Merge->Shuffler->Valid
                label = "Operation Flow"
            }
    }

    subgraph cluster_commons{
        fillcolor="#CD0074" 
        fontcolor="white"
        style="filled"
        label = "Commons"
        commons[fillcolor="white" 
                         style=filled shape=egg]
    }

    SpringBoot -> Shuffler[label=" " ltail=cluster_basic lhead=cluster_app]

    Shuffler -> Entity [label=" " lhead=cluster_domain ltail=cluster_app];

    Shuffler -> RpcAPI[label=" " ltail=cluster_app lhead=cluster_protocol];

    Domain_Service->commons[label=" " ltail=cluster_domain];

    ElasticSearchRepositories-> Repository_API 
    [label="DI" fontcolor="#9FEE00" style="dotted"];

    RedisRepositories-> Repository_API 
    [label="DI" style="dotted" fontcolor="#9FEE00"];
}
上一篇 下一篇

猜你喜欢

热点阅读