LZ 是一个 Python 开发者,在公司做 Python Web 开发。
公司的业务变得越来越复杂,团队也越来越大,感觉“ fat Active Record ORM Model ”的模式有点力不从心: Model 越写越臃肿、有的逻辑不明确应该放在哪里、依赖关系有点混乱、测试困难等等等。
现在觉得需要对业务进行一些分层处理,类似 Java 开发中常见的区分出 DAO 和 service 。
我理解的 DAO 即是只处理数据操作,隔离底层数据操作和逻辑。 service 处理逻辑。
在我的理解里,其中又有两种实现方式:
貌似 Rails 开发也有类似的 Service Object 概念,来抽象业务模型间的逻辑。
LZ 对 Java 基本不懂,仅限大学时候“ Hello world ”水平。现在这套分层实践起来并不是很顺手,对于命名和结构都比较模糊。 service 的参数、返回值,以及实现方式也是跟着感觉走。对以上的理解也是来自网上东拼西凑,乱说一气,感觉有时间应该翻来 Martin Fowler 的书看看。
大家有类似的经验、什么好的实践、建议吗?或者有其它的方式解决现在遇到的问题?
1
msg7086 2016-08-18 02:56:04 +08:00
和 Java 应该关系不大吧。
可以看看设计模式,然后用你上面提到的关键词去爬谷歌 /帖子去,应该会学到不少经验。 |
2
davisz 2016-08-18 04:01:31 +08:00 1
如果只是解决 FAT ORM 的问题可以用两层 Model 来处理,例如 User 表有 UserActiveRecordModel 、 UserModel , AR 一般是框架自动生成后不再任何修改,逻辑写在 UserModel ,如果处理表单校验等逻辑还可以加入 UserFormModel 。
一家之言,仅供参考。 |
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 层里面实现。 总之一句话总结就是,程序架构没有绝对,只有适合,一定要根据你目前的项目来决定。而且一开始你可以对这些决定拿捏不准,没有关系,因为经历还浅,就算是高级架构师也不可能设计出永久不变的架构。等你以后做的设计多了,架构多了就知道,哦这种逻辑很可能会变要抽象出来,哦这种逻辑不太可能变化等等。一开始要有自信,敢去设计敢去实现,就算是后面要改也不要怕,改了说明你学习了进步了! |
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 算了 |
5
tianshiyeben 2016-08-18 09:49:38 +08:00 1
1>首先,团队越来越大是好事情
2>我是做 java 的,大多数项目都是采用你说的 贫血模型 一般架构根据依赖关系从下到上分为, dao->service>controller->view(页面) |
6
ctrlaltdeletel OP |
7
ihuotui 2016-08-19 04:38:17 +08:00 via Android 1
把充血模型当作微服务化就差不多了,把每个方法都是一个微服务,只是这个微服务是在单个应用里面的,而真正的微服务是面向分布式的,记住类似就行了。
|
8
chaleaochexist 2019-03-07 09:34:30 +08:00
大佬有很多体会吗?遇到了类似的问题.
|
9
waibunleung 2021-05-27 19:31:41 +08:00
我有了同样的疑问,看这个帖子还是没有很好地得到解决呀...题主方便交流一下吗?
|
10
waibunleung 2021-05-27 19:32:01 +08:00
@ctrlaltdeletel 我有了同样的疑问,看这个帖子还是没有很好地得到解决呀...题主方便交流一下吗?
|