java 板


LINE

※ 引述《gasbomb (虚空雷神兽)》之铭言: : 大家好, 小弟 java 新手 : 个人的第一个作品因为缺乏经验当初做得苦不堪言 : 肥胖商务层处理完资料後 : 一行一行的把资料填进 VO 里面 : 到了 DAO 又要一行一行的把资料填入 PreparedStatement : 写起来既枯燥又充满重复的程式码 : 後来才了解到这其实是一种 Anemic Domain Model (贫血领域模型) : 最近练习刻新系统, 取消商务层的设计只保留部分的 service : 让大部分的逻辑进入物件, 看看可不可以让自己的系统充血一点 : 但是现在遇到了一些设计上的问题 : 假设今天有一家面包店 : ┌───────┐ ┌────┐ : │bread_category│ │bread  │ : ╞═══════╡ ╞════╡ : │cid (PK)←──┼┐│bid (PK)│ : │cname     │└┼cid (FK)│ : │......    │ │...... │ : └───────┘ └────┘ : bread 是面包(废话) : bread_category 是面包分类 : 今天的逻辑是 cid 可以删除 : 删除以後该分类下面所有的面包全部移到未分类 cid = 0 底下 : 这件事情在 DB 上面做非常简单, 只要两行指令就搞定了 : UPDATE bread SET cid = 0 WHERE cid = 1; : DELETE FROM bread_category WHERE cid = 1; : 因为这是 DB 的操作, 所以在 DAO 里面写一个方法让物件使用也是很合理的 : 但是当我准备这麽作时却有一种不安的感觉浮上心头, 觉得自己好像已经破坏了什麽规 : 照理说更改面包分类是事务逻辑, 应该在 model 层处理, DAO 只负责资料存取 : 从相依性的角度来说, DAO 写太多东西进去也会加重日後换 DB 的负担 : 所以我可能会在 model 这样写 : new Bread().getAll().stream() : .filter(bread -> bread.getCID() == 1) : .forEach(bread -> { : bread.setCID(0); : bread.update(); : }); : 这样打开面包原始码所有功能一目了然, 日後也方便修改 : 但是为了删除一个 cid 叫出所有面包好像哪里怪怪的 : 叫所有面包一起更新也会占用大量的资料库连线 (当初没考虑到大量更新的需求) : 为了解决上面的问题在 DAO 另外写两个方法 : 一个是用 cid 查询面包 : 一个是大量更新面包...... : 这样看起来好像兼顾逻辑跟效能, 可是 DAO 肥大的问题又回来了啊~~~~(崩溃) : 而且这样需要写的程式更多 : 那我还不如回去写那两行 SQL 指令 : 虽然我知道这间面包店可能一辈子都不会有效能瓶颈的问题 : 不过上面的问题确实已经困扰我一天了 : google 找到的也都是一些很 general 的, 介绍设计模式的文章 : 不知道大家在遇到这种问题的时候都是如何决策的? : 如果今天是我的案例, 大家会用哪一种方案解决呢? 原文两位推文在说的还是DB 实作上的取舍, OP烦恼的是Anemic model vs behaviorial-rich model . 我相信你应该有看一些Domain Driven Design (DDD)的入门?单看你的code 有些诡异: 正常设计不会new Bread().getAll() 去取, Model 本身不负责update自己(可能你误解 Anemic model的问题了?) 存取层该是Repository 而不叫DAO 。 回到你的问题,首先你这个”移动category” 的 行为打算放在哪个domain model?假设你有个叫 BreadShop 的model (没有合用的Model 可以弄个Domain Service, 详见DDD). 东西大概会长这样(pseudo code): class BreadShop { void cancelCategory(Category cat, Category moveTo) { // 假设你Category 有指向它拥有的包 cat.moveBreadsTo(moveTo); breadCategoryRepo.update(moveTo); breadCategoryRepo.remove(cat); //又或者长这样 breads=breadRepo.findByCategory(cat); for b in breads bread.putToCaregory(moveTo); // 诸如此类 } } 重点是这个动作也是放在Domain 层内,假 设後来你发现真的太慢,也只需要在Repo 内提供bulk update 的功能,但domain 所 Expose 的API 仍然可以维持不变。 --



※ 发信站: 批踢踢实业坊(ptt.cc), 来自: 223.19.42.108 (香港)
※ 文章网址: https://webptt.com/cn.aspx?n=bbs/java/M.1560382410.A.3BD.html
1F:推 dream1124: 推 06/16 11:50







like.gif 您可能会有兴趣的文章
icon.png[问题/行为] 猫晚上进房间会不会有憋尿问题
icon.pngRe: [闲聊] 选了错误的女孩成为魔法少女 XDDDDDDDDDD
icon.png[正妹] 瑞典 一张
icon.png[心得] EMS高领长版毛衣.墨小楼MC1002
icon.png[分享] 丹龙隔热纸GE55+33+22
icon.png[问题] 清洗洗衣机
icon.png[寻物] 窗台下的空间
icon.png[闲聊] 双极の女神1 木魔爵
icon.png[售车] 新竹 1997 march 1297cc 白色 四门
icon.png[讨论] 能从照片感受到摄影者心情吗
icon.png[狂贺] 贺贺贺贺 贺!岛村卯月!总选举NO.1
icon.png[难过] 羡慕白皮肤的女生
icon.png阅读文章
icon.png[黑特]
icon.png[问题] SBK S1安装於安全帽位置
icon.png[分享] 旧woo100绝版开箱!!
icon.pngRe: [无言] 关於小包卫生纸
icon.png[开箱] E5-2683V3 RX480Strix 快睿C1 简单测试
icon.png[心得] 苍の海贼龙 地狱 执行者16PT
icon.png[售车] 1999年Virage iO 1.8EXi
icon.png[心得] 挑战33 LV10 狮子座pt solo
icon.png[闲聊] 手把手教你不被桶之新手主购教学
icon.png[分享] Civic Type R 量产版官方照无预警流出
icon.png[售车] Golf 4 2.0 银色 自排
icon.png[出售] Graco提篮汽座(有底座)2000元诚可议
icon.png[问题] 请问补牙材质掉了还能再补吗?(台中半年内
icon.png[问题] 44th 单曲 生写竟然都给重复的啊啊!
icon.png[心得] 华南红卡/icash 核卡
icon.png[问题] 拔牙矫正这样正常吗
icon.png[赠送] 老莫高业 初业 102年版
icon.png[情报] 三大行动支付 本季掀战火
icon.png[宝宝] 博客来Amos水蜡笔5/1特价五折
icon.pngRe: [心得] 新鲜人一些面试分享
icon.png[心得] 苍の海贼龙 地狱 麒麟25PT
icon.pngRe: [闲聊] (君の名は。雷慎入) 君名二创漫画翻译
icon.pngRe: [闲聊] OGN中场影片:失踪人口局 (英文字幕)
icon.png[问题] 台湾大哥大4G讯号差
icon.png[出售] [全国]全新千寻侘草LED灯, 水草

请输入看板名称,例如:WOW站内搜寻

TOP