作者gasbomb (虚空雷神兽)
看板Soft_Job
标题Fw: [问题] 系统设计
时间Wed Jun 12 17:08:53 2019
※ [本文转录自 java 看板 #1T0C2gIy ]
作者: gasbomb (虚空雷神兽) 看板: java
标题: [问题] 系统设计
时间: Wed Jun 12 17:06:45 2019
大家好, 小弟 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 的, 介绍设计模式的文章
不知道大家在遇到这种问题的时候都是如何决策的?
如果今天是我的案例, 大家会用哪一种方案解决呢?
--
╔═◢ ◣═╦╦═════╦═════╗
║
◤◤◤ ◥ ╠╣
飞鸟ももこ╠═╗ ║
║ ▇ ▇ ║╚═════╝ ╚═╦═╣
║ ▌ ● ● ▌ ║╔══════╗╔═╩═╣
║
◤ ◥
︺█◤
◥╠╣
Momoko Asuka╠╝ ║
╚◣◢ ▄▂▄ ◣◢╩╩══════╩════╝
--
※ 发信站: 批踢踢实业坊(ptt.cc), 来自: 60.248.96.211 (台湾)
※ 文章网址: https://webptt.com/cn.aspx?n=bbs/java/M.1560330410.A.4BC.html
※ 发信站: 批踢踢实业坊(ptt.cc)
※ 转录者: gasbomb (60.248.96.211 台湾), 06/12/2019 17:08:53
1F:→ BlacksPig: 或用SQL trigger? 06/12 17:17
2F:推 MOONY135: 我会写sql的sp吧 06/12 18:03
3F:→ MOONY135: 我觉得商业逻辑写在要上板的东西写死了 要改会很麻烦 sp 06/12 18:16
4F:→ MOONY135: 真的比较无痛 06/12 18:16
5F:→ x246libra: 之前上资料库的人,讲者是建议目前开发,都尽量不要用s 06/12 20:01
6F:→ x246libra: p 06/12 20:01
7F:→ lwtech: 不懂管理和程式的管理,你有没有用 SP 都一样 06/12 20:07
8F:→ MOONY135: 可以说一下为什麽不建议的理由吗 然後替代做法是? 06/12 20:09
9F:→ sextitanic: dao1->更改面包分类, dao2->删除面包分类 06/12 20:19
10F:→ sextitanic: service->删除面包分类, 使用dao1再使用dao2 06/12 20:20
11F:→ alan3100: SP有cacheplan问题.preparedstatement配framework弹性高 06/12 22:15
12F:推 jass970991: 拆两步就好 dao层还是要有一点弹性 只是谈性到哪要决 06/13 00:02
13F:→ jass970991: 定一下 06/13 00:02
14F:推 srwhite: 同sextitanic 然後service再加个transactionl 06/13 12:36
15F:→ ketrobo: 逻辑正确优先,易读易维护次之,效能要注意的问题写在注解 06/13 21:36
16F:→ ketrobo: 里,验收过了赶快忘掉这些事 06/13 21:36
17F:→ ketrobo: 大部份你认为兼顾的情况其实都不是真正的兼顾,当那段20 06/13 21:55
18F:→ ketrobo: %的程式占用80%的系统资源却无法在时限内完成工作时,你 06/13 21:55
19F:→ ketrobo: 会放弃兼顾,改追求效能,当其他80%的程式码都不属於那占 06/13 21:55
20F:→ ketrobo: 用80%系统资源的20%程式码时,我们也很少有足够的数据去 06/13 21:55
21F:→ ketrobo: 界定所谓的兼顾 06/13 21:55
22F:推 iamshiao: 这不算很复杂的业务逻辑我也会选 sp 06/14 00:43