cp-ddd-framework icon indicating copy to clipboard operation
cp-ddd-framework copied to clipboard

默认步骤编排不支持多聚合情况

Open littlebingo opened this issue 3 years ago • 12 comments

步骤编排作为扩展点,只能有一个默认实现,那么两个聚合,比如用户和角色,创建用户的步骤编排和创建角色的步骤编排不能各自实现,如果两个默认的实现写在一起,pattern或partner重新编排创建用户和创建角色都需要重写

littlebingo avatar Dec 02 '20 06:12 littlebingo

你给的例子,我没有看懂,没有get到你的意思,能再具体点吗

BTW:扩展点,是可以通过Reducer进行叠加执行的,并不是只能一个默认实现

funkygao avatar Dec 03 '20 14:12 funkygao

换个例子,可能和上面的问题说的不是一回事哈。比如一个微服务里可能有A和B两个聚合,在一个bp前台应用下,创建A聚合的时候有个个性化字段需要实现IModelAttachmentExt扩展点,创建B聚合的时候也有个个性化字段需要实现IModelAttachmentExt扩展点, 但是同一个扩展点的@Extension注解code不能重复,所以IModelAttachmentExt的两个扩展点实现不能code都等于比如isv,这个应该解决呢?

littlebingo avatar Dec 04 '20 00:12 littlebingo

sorry for being late

funkygao avatar Dec 10 '20 10:12 funkygao

一个扩展点的实现,必定对应一个确定的业务场景,因此extension.code不能重复。

你的例子,A聚合和B聚合分别实现IModelAttachmentExt就好了,为什么要code=isv呢?

funkygao avatar Dec 10 '20 10:12 funkygao

@Slf4j
@Extension(code = IsvPartner.CODE, value = "isvCustomModel", name = "ISV前台的订单个性化字段处理逻辑")
public class CustomModelExt implements IModelAttachmentExt<IOrderModel> {

以上为dddplus-demo中的isv对应的个性化字段扩展点实现部分代码。

void registerExtensionDef(ExtensionDef extensionDef) {
        Class<? extends IDomainExtension> extClazz = extensionDef.getExtClazz();
        if (extensionDefMap.containsKey(extClazz)) {
            throw BootstrapException.ofMessage("Partner(code=", code, ") can hold ONLY one instance on ", extClazz.getCanonicalName(),
                    ", existing ", extensionDefMap.get(extClazz).toString(), ", illegal ", extensionDef.toString());
        }

        extensionDefMap.put(extClazz, extensionDef);
    }

以上为ddd-plus中PartnerDef中的部分代码,表明isv前台的IModelAttachmentExt只能有一个扩展点, 那么如果demo服务中isv前台还有除订单聚合外的其他聚合需要实现个性化字段扩展点该如何实现?

littlebingo avatar Dec 13 '20 08:12 littlebingo

明白你的意思了。isv前台的IModelAttachmentExt只能有一个扩展点:不是这样的

isv可以实现多个IModelAttachmentExt,每个分配不同的code,然后实现多个Pattern,在Pattern里实现路由逻辑就可以在isv里实现多场景了

funkygao avatar Dec 15 '20 11:12 funkygao

例如,isv里要区分“大件”和“中小件”这2个细分场景,那么它可以定义2个Pattern:

Pattern1:

if !order.isISV() {
    // 首先来的这个订单要属于isv的
    return false
}

// 再判断是否是中小件
return order.isSmallPiece()

Pattern2:

if !order.isISV() {
    // 首先来的这个订单要属于isv的
    return false
}

// 再判断是否是大件
return order.isLargePiece()

funkygao avatar Dec 15 '20 11:12 funkygao

个人很喜欢funkygao的这个项目,给我很大启发:) 我提个相关的问题:楼上的用法是把Pattern作为Partner的的细分概念来使用的。但是代码注释中对Pattern的定位是“横向视角”,而Partner是“垂直视角”,看起来跟Partner跟Pattern应该是正交不相干的。 希望funkygao能够给予解释:)

 * <p>{@link Pattern}通常属于中台CP自己要处理的个性化业务,前台BP往往不会参与</p>
 * <p>横向视角把扩展点进行聚合,属于水平业务,可以叠加</p>
 * <p>所谓横向视角,相当于AOP里的Aspect</p>
 * <ul>如何理解{@code Pattern}与{@code IDomainExtension}?
 * <li>{@code Pattern},相当于把散落在各处的某个业务逻辑{@code if} 判断条件,收敛到{@code Pattern}里,使得这些业务判断显式化,有形化,有了化身,并有了个名字(UL)</li>
 * <li>扩展点,相当于把{@code if} 后面的code block显式化,有形化</li>

aking222 avatar Sep 16 '21 16:09 aking222

@aking222 具体的使用,Partner通常是业务前台方,Pattern是中台方(中台内部也有多场景情况:业务多态)

一个业务如果业务前台方参与开发,那么一个domain model下,一定只属于某1个Partner的,不可能交叉; 但Pattern下,可能交叉也可能冲突,因此它有了优先级的概念

funkygao avatar Sep 17 '21 06:09 funkygao

理解了,感谢回答

aking222 avatar Sep 25 '21 03:09 aking222

一个domain model下,一定只属于某1个Partner的,不可能交叉

@funkygao 首先我也和喜欢这个项目,但里面一些概念还在理解中,比如关于上面这句说法,还想请教一下,能举个例子吗?为什么一个domain model一定只属于一个Partner?谢谢。

caryfang avatar Apr 21 '22 14:04 caryfang

@caryfang Partner是为了企业内部前台业务特点的抽象,一个业务一定只属于一个业务方,这是业务特点,而Partner就是为这个业务特点的技术抽象。如果交叉,就使用Pattern

一个domain model是中台的业务抽象模型,它跟Partner/Pattern无关

funkygao avatar Apr 25 '22 00:04 funkygao