Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Domain 层的出入参要 domain 层自己维护的话不会爆炸多吗?还是都用 entity?总不能引用 client 包下的吧 #552

Closed
felix9ia opened this issue Sep 23, 2024 · 6 comments

Comments

@felix9ia
Copy link

felix9ia commented Sep 23, 2024

前提: 作者说 domain 领域是应用的核心,不依赖任何其他层次

我的疑惑是,为了保持domain层的独立性,在 domain 层,入参该不该新建 DTO 来支持?

比如创建店铺 shopGateway.createShop(Shop newShop)

方案1: 如果 newShop 直接用 entity ,但新建店铺又不需要 shopNo、ctime、utime 等字段。

方案2: 难道在给 domain 包下新增一个 DTO 包,里面放着 DTO 或者 Command 或者 query ?这个数量又是爆炸的多

方案3:总不能去引用 client 包的 Command 和 query 吧。client 本身是给 SDK 用的,有些不暴露给 client 的接口反而把不暴露接口的入参都定在了client 层,显然不合理。

方案4:入参都用字段做参数,比如(String shopName, String shopDesc),这明显不具备重构时的扩展性。

我现在打算都用 entity 做入参。因为我看了官方的 craftsman 的 gateway,入参要么都是用字段做参数,要么就是引用了 entity。

而且其他方案明显有缺陷....难道这就是代价?

BTW,COLA 在 App 层 实践的 CQRS 的收益到底在哪里?我用 xxQueryService 和 xxCommandService 是不是也能实现读和写的隔离...

@felix9ia
Copy link
Author

felix9ia commented Sep 24, 2024

新建一个 common 模块,来放置 这些 cmd 和 query 应该是合适的,总不能让这些 cmd 和 query 都止步于 app 层吧。

就不知道符不符合 domain 领域不依赖任何层次的要求

@felix9ia
Copy link
Author

cmd 和 query 还是不能跨过 domain 入侵到 gateway 上,
原因 1:这样在 app 层做完的 cmd 和 query 的 Assembler,又得在 gataway 的 impl 里重新做一遍,
原因2: 而且在 domain 上做完的类似状态转化的动作, gateway 就感知不到了,相当于 gateway 成了 app 层的奸细, 把 domain 架空了.....

看来 domain 层智能选择我上面的方案1,所有gateway 上的入参都得用 entity

@felix9ia
Copy link
Author

要想不浪费 cmd 和 query 这些参数,感觉需要用 domainservice 把 app层和 gateway 层彻底隔离起来,让 domainservice 来承接 cmd 和 query ,

但是,这样 domainservice 又把 app 层的 service 架空了,而且 domainservice 的角色似乎也不应该干这事儿....

所以 cmd 和 query 只能止步于 app 层....

@felix9ia
Copy link
Author

felix9ia commented Sep 24, 2024

我应该是找到一个比较合适的方案,这样也调用的 domain 的积极性。cmd 和 query 也不浪费

拿更新店铺位置的动作来说。

在 App 层,分成三个步骤,查询店铺、更新位置,保存,重点是更新位置要放在 entity 里, setLocation(ShopLocationCmd shopLocationCmd, Long userId) 。

    public Response updateShopInfoLocation(ShopLocationCmd shopLocationCmd) {
        Long userId = UserContext.currentUserId(true);

        Shop existShop = checkExistShop(shopLocationCmd.getShopNo());
        existShop.setLocation(shopLocationCmd, userId);
        shopGateway.updateShop(existShop, userId);
        return Response.buildSuccess();
    }

在 entity 中,把 ShopLocationCmd 作为入参

    public void setLocation(ShopLocationCmd shopLocationCmd, Long userId) {
        this.setShopAddressDesc(shopLocationCmd.getShopAddressDesc());
        this.setShopLatitude(shopLocationCmd.getShopLatitude());
        this.setShopLongitude(shopLocationCmd.getShopLongitude());
        this.setShopStatusCode(ShopStatus.ACTIVE.getCode().longValue());
    }

这样子,domain 层充分利用了 cmd,也不会导致可读性降低,可能让其他开发者误以为更新位置的操作会涉及到其他不相关的字段,增加了代码审阅的复杂性。

至于 domain 层 是否与 client 包耦合,我觉得 client 包层的 cmd 和 query 本身就是和 app 层耦合的, controller 调整后,client 包需要跟随着 app 层调整,domain 层也逃不过。

所以, domain 和 client 包耦合这事儿和去冗余和可读性比起来,我觉得收益比较大,要是觉得 client 包不合适,大不了 cmd 和 query 迁移到 common 包里。
:)

@felix9ia
Copy link
Author

我发现,让 domain 依赖 client 包还是不合适

但我的困惑是脚手架初始化项目时,domain 就依赖了 client 包,既然添加了依赖,总有依赖的根据吧?

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>com.unrealdie.stall</groupId>
        <artifactId>stall-api-parent</artifactId>
        <version>1.0-SNAPSHOT</version>
        <relativePath>../pom.xml</relativePath>
    </parent>

    <artifactId>stall-api-domain</artifactId>
    <packaging>jar</packaging>
    <name>stall-api-domain</name>

    <dependencies>
        <dependency>
            <groupId>com.unrealdie.stall</groupId>
            <artifactId>stall-api-client</artifactId>
        </dependency>

        <!-- COLA components -->
        <dependency>
            <groupId>com.alibaba.cola</groupId>
            <artifactId>cola-component-domain-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>com.alibaba.cola</groupId>
            <artifactId>cola-component-exception</artifactId>
        </dependency>
        <!-- COLA components End-->
    </dependencies>
</project>

@felix9ia
Copy link
Author

#557

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant