1
connection 2021-07-29 22:11:27 +08:00 4
1. 不建议 "重复" => "抽象",错误的抽象比多余的重复更可怕 https://sandimetz.com/blog/2016/1/20/the-wrong-abstraction 。
2. 重构是一个持续的过程。 3. 可以找本《 clean code 》找找感觉。 |
2
zstone123 OP |
3
hackyuan 2021-07-29 22:43:36 +08:00 1
即使是错误的抽象也要抽象,需要刻意训练,多练多使用,隔半个再看看之前抽象的是否恰当。
其余的就是多看开源代码,学习他们的技巧。 |
4
revlis7 2021-07-29 23:12:31 +08:00 1
我的个人感受是,合理的抽象解耦 > 冗余代码 > 粗暴的代码封装,但实际情况是没有那么多时间给你做抽象解耦,尤其是频繁变动的业务逻辑,所以更多的时候选择冗余代码。除非你有完备的测试,否则你永远不知道你的一次改动会造成多大的影响。
|
5
3dwelcome 2021-07-29 23:33:08 +08:00 4
别听一楼的,编程路想要走的久。就要不断提取共同代码,不积累自己的类库,否则又怎么会有技术成长?
所谓“错误的抽象”,无非就是模块之间的耦合性过强。仔细思考,把模块一个个抽丝剥茧即可。 还有那句“duplication is far cheaper”,我最恨的就是写一堆重复代码了,时间一久,你完全无法分辨哪些代码能删,哪些不能。 |
6
dozeboy 2021-07-29 23:46:57 +08:00 1
尝试把重复代码提取到足够小的单元,类或者方法中。根据「单一职责」「组合优于继承」等设计原则来优化代码,慢慢就有进步了。
|
7
ayase252 2021-07-29 23:51:56 +08:00 1
可以看看重构第二版,了解一下代码中的坏味道。
小步重构去掉坏味道,留下来的就是架构比较好的代码了 |
8
xuanbg 2021-07-30 04:38:34 +08:00 2
抽象意味着剥离特性,需要对业务有非常深刻的理解,认知的深度已经触及本质而非停留在表面。譬如关系数据库,就是对一般数据的结构及存储需求的抽象。
上面几楼说的都不是抽象而仅仅是封装。对于我们的业务代码而言,封装的重要性其实远高于抽象。 |
9
chenqh 2021-07-30 05:52:02 +08:00 1
实在不行用多继承,每个继承只做一类事情
|
10
felixin 2021-07-30 07:34:31 +08:00 via Android 2
业务逻辑用 uncle bob 的 clean code 是正解。
抽象和重复是一体两面的,并没有哪个更好的说法,一切都得看架构设计的权衡和利弊分析。 dry 原则只是初级阶段,不用死守。 |
11
e583409 2021-07-30 07:52:04 +08:00 1
重复代码 还有一个坏处就是维护与测试成本高 改了一个地方 可能还要修改另外一个地方 对代码有追求本身就是一种自我提升的手段和途径
不然 CRUD 怎么提升 |
12
yidinghe 2021-07-30 08:07:38 +08:00 via Android 1
想要建立抽象的思维方式,最好就是多读热门框架的代码,看懂那些套路。
|
13
312ybj 2021-07-30 08:21:23 +08:00 1
还是实践出真知, 你们系统里有优秀的代码案例吗,如果有的话可以参考下。如果没有,我建议从模板方法开始入手,自己写一个接口,写一个抽象类, 公共的业务放到上层,个性化的需求放在实现类里。 抽象是个过程,可以一边写代码,一边画流程图 uml 图,熟能生巧。
|
14
a719031256 2021-07-30 08:39:09 +08:00 1
首先你得确定你做的业务需求变化大不大频繁不频繁
如果不大不频繁的话可以做合并 反之则不建议做合并,更应该做拆分 |
15
fpure 2021-07-30 09:08:51 +08:00 1
只能说很多人误用了 DRY 原则( DRY 原则和开闭原则是我见过最多人误用的编程原则)。实践 DRY 原则应该明白什么应该抽象什么应该冗余,我认为抽象的是同一问题的解决方案,冗余的是代码。所以并不是两段代码看起来相似就应该抽象,而是要考虑这两段代码是否是在解决本质上同一问题。
|
16
ebingtel 2021-07-30 09:23:32 +08:00
写测试,是重构的前提
|
17
skys215 2021-07-30 09:29:51 +08:00
了解一下领域驱动设计?
|
18
JJsty1e 2021-07-30 09:30:43 +08:00 via iPhone
@e583409 虽然我不推崇写重复代码,但是你这个例子不恰当,因为有时候你也会发现按需要改了一个地方,引用这份代码的另一个地方却出了问题所以根源在于,在代码变更过之后,测试能否覆盖到
|
19
qq648988741 2021-07-30 09:31:13 +08:00
补充个点吧,如果没想好怎么做,先尝试写写文档,整理清楚思路,再来看看怎么做
|
20
yyysuo 2021-07-30 10:14:35 +08:00 1
把足够独立的逻辑,小范围的封闭成积木,然后用积木搭建大厦。不要想着造大的积木。
|
21
xwayway 2021-07-30 10:35:28 +08:00
最近也在提升自己的代码能力,刚好新公司也会很尽职 review 代码,给一些意见。尽量做到领域内聚合,不做太多分支。遇到能快速返回的地方尽量快速返回。以下是我觉得对不同逻辑处理比较好的一种方式,这样的话,看代码的人不用在你的 if else 里面转晕了头
private final Map<Order.Type, BiConsumer<Order, SubmitParam>> EXTRA_PARAM_RESOLVER = ImmutableMap.<Order.Type, BiConsumer<Order, SubmitParam>>builder() .put(Order.Type.A, this::resolveForA) .put(Order.Type.B, this::resolveForB) .put(Order.Type.C, this::resolveForC) .build(); |
22
fengjianxinghun 2021-07-30 10:42:09 +08:00
复制粘贴就是最好的抽象
|
23
chenqh 2021-07-30 13:35:05 +08:00
@fengjianxinghun 我觉得不对,我之前做页面,create 和 update 的页面不一样,管理员和其他用户用户同一种页面也分开,后来加东西,加死我了
|
24
zsyld 2021-07-30 15:13:42 +08:00 1
有卵用,代码干净清爽,业务分类清晰,很少出 bug,就算出 bug 也很快解决了,沙雕老板反而觉得没什么事呀,这人没多大用呀,涨工资亏的慌呀。不如换个便宜的应届生呀。。。
我现在是功能实现就好,爱咋滴咋滴,能 cmd+c/v,绝不费脑筋去抽象,出 bug 能甩锅就甩锅,缝缝补补凑合用得了 |
25
golangLover 2021-07-30 20:41:01 +08:00 via Android
@xwayway 这个 biconsumer 的应用有例子吗?好像平常就在 stream 里见过,但和你这个好像不太一样
|
27
daxiguaya 2021-08-01 13:06:17 +08:00 1
放几篇文章出来看看有没有帮助.
https://blog.cleancoder.com/uncle-bob/2014/05/08/SingleReponsibilityPrinciple.html 、 http://sunnyday.mit.edu/16.355/parnas-criteria.html 如果看了些 DDD 相关的资料觉得比较抽象的话,推荐一篇我最近看的: https://tech.youzan.com/dddclue/ |