[问题] 系统设计

楼主: gasbomb (虚空雷神兽)   2019-06-12 17:06:45
大家好, 小弟 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 的, 介绍设计模式的文章
不知道大家在遇到这种问题的时候都是如何决策的?
如果今天是我的案例, 大家会用哪一种方案解决呢?
作者: LZN (秋)   2019-06-12 17:34:00
如果把分类跟面包的关系用relation table来记录呢?也就是中间多一层table(cid,bid), 然后面包table的cid移除
作者: ssccg (23)   2019-06-12 20:06:00
FK直接定义on delete set default就好这是资料模型层的constraint,跟事务逻辑没关系啊对一个关联式资料模式来说,删一笔有被关联的资料本来就隐含了对关联资料的处理了
作者: haha02 (来人!上夹棍!)   2019-06-14 19:34:00
你可以考虑面包那边用on delete set null之类的DB功能 另外去调整未分类的查询逻辑就好 感觉比较简单打完才发现我跟ssccg讲的一样XD
作者: jej (晃奶大馬桶)   2019-06-15 08:17:00
按照你的sql语法去思考 例子中java语法和sql是两种不同情境而且category那张表是code mapping去删除他做啥?

Links booklink

Contact Us: admin [ a t ] ucptt.com