12|代码实现(下):怎样更加“面向对象”?
为“修改组织”功能开卡
- 深入了解
- 翻译
- 解释
- 总结
本文深入探讨了如何更加“面向对象”地实现代码,主要围绕封装、继承和多态这三个面向对象的特征展开讨论。作者首先讨论了修改组织功能的开发,结合封装和继承的应用。随后,详细介绍了初步完成程序功能的代码实现,包括OrgService和OrgHandler的具体实现。文章还讨论了如何提高应用API的封装性,通过编写单独的参数DTO来简化入口参数的JSON格式,提高系统的封装性。此外,还提出了提高领域对象的封装性的方法,包括限制getter和setter的数量,以及用表示业务含义的接口代替简单的setter和getter。另外,文章还介绍了如何用继承消除重复,以及编程风格的回顾。总的来说,本文通过实际的代码实现和技术讨论,深入浅出地介绍了如何更好地实现面向对象的编程。 通过本文,读者可以学习如何利用封装和继承来提高代码质量。作者通过实例详细阐述了如何在API和领域对象层面实现封装,以及如何利用继承减少代码重复。此外,文章还对编程风格进行了回顾,强调根据实际情况进行权衡。读者可以通过本文学习到如何利用面向对象的编程思想来提高代码质量和可维护性,为实际项目开发提供了有益的指导。
《手把手教你落地 DDD》,新⼈⾸单¥59
全部留言(22)
- 最新
- 精选
- 别天神置顶1、对于包级私有权限来增强封装我觉得是可行的,领域对象的更改我认为只能通过领域方法来做,一方面保护了领域状态的一致性,另一方面也能最大程度确保开发人员随意更改状态,所以通常我觉得 领域对象内部不应该存在set方法,取而代之的是更加“表意”的领域方法。 2、但是从存储介质进行领域对象恢复的时候,有时候又需要set方法,恢复领域对象应该无需关心业务,所以存在一些矛盾点: - 为了保护业务一致性和封装,不暴露set - 为了恢复领域对象,我们需要set,更进一步,为了使用工具类进行属性的copy还要求set必须是public的 在实际实现上,我采用了一些折中的方案, - 领域对象自身不具备set方法,有一个包级别的领域对象Builder,Builder中承载set,如@Builder(setterPrefix = "set", toBuilder = true, access = AccessLevel.PROTECTED) - 这样可以在同一个包内访问builder, 构建builder实例,同时因为setXxx是public的,还能解决属性copy问题 - builder.build()可以转换成领域对象 - 可以建一个FQN一样的包(和仓储实现同模块),里面仅存放着 持久化对象到领域对象的转换,因为包名一样,可以访问到set
作者回复: 这个思路不错👍🏻
2023-02-04归属地:上海4 - Jaising还在犹豫是否要翻过墙的时候,就先把帽子丢到墙的另一边,剩下的自然会有办法。 以我切身体会仅仅迭代一学完就治好了不少DDD恐惧症,真的感谢钟老师和编辑小新的最小闭环设计,对零基础入门DDD不要太好,平时不愿记笔记的我都能跟着老钟医通过重新演绎更新了五篇——事件风暴、领域建模、数据库设计、分层架构和代码实现,小结与导航在这里:https://juejin.cn/post/7190270005072625723。 辞旧迎新,给自己的最好礼物就是持续学习,学以致用,换取职业生涯不断上台阶的可能,终身成长就有了立身之本,用来抵御各类危机。新的一年从入门DDD开始,会发现软件开发的世界照进了新的光,让我们一起加油! 祝各位兔年快乐!
作者回复: 很佩服你的学习精神,加油!
2023-01-20归属地:安徽212 - binhandler如果不依赖数据库,这部分业务逻辑好像也可以放到领域对象里面。有没有一个好的边界区分?
作者回复: 目前的风格就是以是否依赖数据库来区分,参考课程中对代码风格的总结。当然,也可以制定你自己的代码规则。
2022-12-31归属地:广东6 - aoe原来我现在的编程风格是偏过程式的 思考题 1. 可以。这样确实可以增强封装。再疯狂一点,可以使用 Java 模块化技术,让反射都无法打破封装。 2. 没发现不应该有 getter 的属性。
作者回复: 关于第2问,可以扩展一下。比如对于状态,如果用 isEffective(), isTerminated()之类的方法封装了,那么未必要用 getStatus()了。
2023-01-03归属地:广东23 - H·H领域对象是否可以通过依赖注入的方式注入 仓储Repository?
作者回复: 你是指把repository注入领域对象,从而使领域对象可以访问数据库吗?理论上可以,就看你要不要选这种编程风格。
2023-01-30归属地:上海32 - 6点无痛早起学习的和尚一些问题: 5. 为什么在 addOrg 加事务?里面就一个 save 操作,是否没必要加@Transactional 6. 很多用@Autowired 注入的属性,有些是 final,有些不是 final,这个有什么讲究吗?
作者回复: 加了@Transactional不会有什么坏处,如果以后逻辑更复杂了,可以避免忘掉。 @Autowired注入的属性一般都用final,我有些地方没注意,等我稍后统一改一下
2023-01-17归属地:北京2 - Breakthrough钟老师,DDD设计完成后的交付文档一般长啥样,是不是也要做类似设计需求说明书的WORD档。如果是,是否有相关的模板参考下?
作者回复: 关键是有领域模型、词汇表、业务规则表,可以把这几个制品融入到目前使用的文档中。
2023-07-17归属地:北京1 - 龙腾老师请教一下,“第三,应用服务可以读写数据库。”这块没太明白,什么情况下读写数据库不包含领域知识呢?咱们的数据库设计不就是按照领域来划分设计的吗,只要读写都是在领域内进行的吧?
作者回复: “调用Repository,从数据库里取出一个领域对象”这句话是不需要和业务人员谈的,因此这句话反应的逻辑不包含领域知识,
2023-01-02归属地:广东1 - 路上类似撤销这部分校验逻辑,目前看领域对象自己就可以校验,目前是在外层进行的校验之后调用领域方法进行状态变更 是否可以在领域对象变更状态的方法内部自己进行校验呢
作者回复: 没错,后面就会讲到这个思路。
2023-12-15归属地:北京 - 末日,成欢老师,有一些疑问。 第一,领域对象不访问数据库。 这里的不访问数据库,是指可以在领域服务中访问,而不要在领域对象中里访问数据是吧。 第二个疑问, 修改组织信息和撤销组织, 第一步骤是查询组织是否为空, 这应该也是领域服务中的逻辑判断,应该也放在领域服务中把。这里直接放在应用服务的考虑是什么? 还有为何save方法没有放到领域服务中?这里的应该不是应用逻辑把? 第三个疑问, 事件风暴法中的第一个识别领域事件,这个领域事件维度多大呢,比如我想进行任务分解, 应该在哪个流程进行分解才合适呢? 目前代码看到这里,还是偏向过程化, 只是利用了一些软件的设计原则(比如solid),代码更业务化, 还没理解有啥好处
作者回复: 第一:是的 第二:为了避免累赘,或者你看能否有更好的写法贡献出的? 对save的调用不算领域逻辑 第三:粒度大体相当于一个事务 本课程的的代码是偏过程式的。或许以后有时间给大家讲讲真正的面向对象编程是什么样。
2023-06-13归属地:陕西