关于业务分层的疑惑: 贫血模型 or 领域模型 or 都是扯淡? - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
请不要在回答技术问题时复制粘贴 AI 生成的内容
cadl
56.85D
V2EX    程序员

关于业务分层的疑惑: 贫血模型 or 领域模型 or 都是扯淡?

  •  1
     
  •   cadl 2016-08-18 01:42:23 +08:00 6731 次点击
    这是一个创建于 3345 天前的主题,其中的信息可能已经有所发展或是发生改变。

    LZ 是一个 Python 开发者,在公司做 Python Web 开发。

    公司的业务变得越来越复杂,团队也越来越大,感觉“ fat Active Record ORM Model ”的模式有点力不从心: Model 越写越臃肿、有的逻辑不明确应该放在哪里、依赖关系有点混乱、测试困难等等等。

    现在觉得需要对业务进行一些分层处理,类似 Java 开发中常见的区分出 DAO 和 service 。

    我理解的 DAO 即是只处理数据操作,隔离底层数据操作和逻辑。 service 处理逻辑。

    在我的理解里,其中又有两种实现方式:

    1. “贫血模型”。数据对象简单,逻辑实现在类似过程式的“事务脚本”中,操作 DAO 进行数据处理。能想到的缺点是可能仍要写一些 service 间重复的逻辑。
    2. “领域模型”。对业务对象抽象为一个 domain object ,处理自身相关逻辑。上层 service 协调各个 domain object 处理逻辑。对业务理解和抽象的要求更高,感觉 service 和 domain object 在结构的组织上也比较麻烦。

    貌似 Rails 开发也有类似的 Service Object 概念,来抽象业务模型间的逻辑。

    LZ 对 Java 基本不懂,仅限大学时候“ Hello world ”水平。现在这套分层实践起来并不是很顺手,对于命名和结构都比较模糊。 service 的参数、返回值,以及实现方式也是跟着感觉走。对以上的理解也是来自网上东拼西凑,乱说一气,感觉有时间应该翻来 Martin Fowler 的书看看。

    大家有类似的经验、什么好的实践、建议吗?或者有其它的方式解决现在遇到的问题?

    10 条回复    2021-05-27 19:32:01 +08:00
    msg7086
        1
    msg7086  
       2016-08-18 02:56:04 +08:00
    和 Java 应该关系不大吧。
    可以看看设计模式,然后用你上面提到的关键词去爬谷歌 /帖子去,应该会学到不少经验。
    davisz
        2
    davisz  
       2016-08-18 04:01:31 +08:00   1
    如果只是解决 FAT ORM 的问题可以用两层 Model 来处理,例如 User 表有 UserActiveRecordModel 、 UserModel , AR 一般是框架自动生成后不再任何修改,逻辑写在 UserModel ,如果处理表单校验等逻辑还可以加入 UserFormModel 。

    一家之言,仅供参考。
    kitalphaj
        3
    kitalphaj  
       2016-08-18 09:00:24 +08:00   2
    你说的这个问题在 Rails 里面挺常见的,特别是 Rails 的 Model 已经默认实现了数据库的一些基本操作不需要你再自己写。这种时候你就只需要考虑到底是把业务逻辑(Business Logic)放在 Service 层还是放在 Model 层。

    一种思路是完全把逻辑放在 Service 里面, Model 仅仅是存数据。这种方法的好处是 Model 层会比较轻,就算是以后某个 Model 变了,比方说以前是 FullName ,现在你需要换成 FirstName 和 LastName ,那对于 UI 层的 Controller 或者 View 来说,这个变化是透明的,只需要 Service 里面把获取名字的函数调整一下就好了。但是这个设计的问题也很明显,就像你说的, Service 层会写很多重复代码,比如明明可以直接
    Model.Name 的你就需要用 Service 的方法包装一层。

    我个人觉得设计模式从来都不是绝对的,对于某些系统来说这种设计可能很适用,但是对别的系统这种设计很可能就太累赘。比如上面提到这种设计,如果你觉得现在系统处于项目早期,很多 Model 都有可能会进行变化,那么你完全可以把易变的那些逻辑在 Service 里面封装,其它一些你觉得长时间都不会变的,比如某个时间的本地化处理,那么完全可以在 Model 层里面实现。

    总之一句话总结就是,程序架构没有绝对,只有适合,一定要根据你目前的项目来决定。而且一开始你可以对这些决定拿捏不准,没有关系,因为经历还浅,就算是高级架构师也不可能设计出永久不变的架构。等你以后做的设计多了,架构多了就知道,哦这种逻辑很可能会变要抽象出来,哦这种逻辑不太可能变化等等。一开始要有自信,敢去设计敢去实现,就算是后面要改也不要怕,改了说明你学习了进步了!
    feiyuanqiu
        4
    feiyuanqiu  
       2016-08-18 09:26:28 +08:00 via iPhone   2
    企业应用架构模式那本书对 ddd 开发并没有写得很清楚,很多概念其实在日常开发中,在使用 orm 中已经接触并实践过了,看它收获不大

    最近在看 implementing domain driven design 这本书,内容挺丰富的


    以下是个人的一些牢骚

    我之前非常纠结的是采用 DataMapper 类型的 orm 之后,因为会给每个表建立一个对应的实体,我有点不清楚业务逻辑该放在哪好了,普遍推荐的是实体就仅仅是个做数据映射的 pojo ,数据持久化操作放到 repository 里面,领域逻辑放到 service 里面,业务流程逻辑放到 controller 里面…但因为我用的是 php ,在网上找到的一些资料又说 weak object 是种反模式,比如 doctrine 的作者之一,在他的 doctrine 最佳实践的 ppt 里就说,实体应该要有行为,不然和数组有什么区别…

    然后找了一些 php 的 ddd 开发实例观摩,发现似乎过于复杂了,几乎把业务里所有东西都对象化了, id 这些不可变元素要做成 value object ,把它的行为都扔到 vo 里面,但是实际上很少会对 id 这些东西有什么复杂的操作,同样还有对 repository 的抽象,单独建了 instruction 这么一层来存放不同的数据存储,但是实际工作中很少会出现更换数据库这种事吧?有必要吗

    我觉得像 php , python 这种语言,并不需要全盘地采纳 ddd 的思想,不然还不如直接用 java 算了
    tianshiyeben
        5
    tianshiyeben  
       2016-08-18 09:49:38 +08:00   1
    1>首先,团队越来越大是好事情

    2>我是做 java 的,大多数项目都是采用你说的 贫血模型

    一般架构根据依赖关系从下到上分为, dao->service>controller->view(页面)
    cadl
        6
    cadl  
    OP
       2016-08-18 14:10:12 +08:00
    @kitalphaj 多谢回答,很棒。
    @feiyuanqiu 已标注想读。的确应该是以解决问题为目的出发,单纯模仿就有些过了。
    ihuotui
        7
    ihuotui  
       2016-08-19 04:38:17 +08:00 via Android   1
    把充血模型当作微服务化就差不多了,把每个方法都是一个微服务,只是这个微服务是在单个应用里面的,而真正的微服务是面向分布式的,记住类似就行了。
    chaleaochexist
        8
    chaleaochexist  
       2019-03-07 09:34:30 +08:00
    大佬有很多体会吗?遇到了类似的问题.
    waibunleung
        9
    waibunleung  
       2021-05-27 19:31:41 +08:00
    我有了同样的疑问,看这个帖子还是没有很好地得到解决呀...题主方便交流一下吗?
    waibunleung
        10
    waibunleung  
       2021-05-27 19:32:01 +08:00
    @ctrlaltdeletel 我有了同样的疑问,看这个帖子还是没有很好地得到解决呀...题主方便交流一下吗?
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     3353 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 25ms UTC 10:42 PVG 18:42 LAX 03:42 JFK 06:42
    Do have faith in what you're doing.
    ubao snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86