我负责用 Go 写一个从 Redis 或 MySQL 中取数据,并且通过 http 协议将数据返回给客户端。
现在有三个查询,分别是当前,分时,分天的数据。因为发现重复的代码很多,所以我就想通过接口来让它们达到泛化的目的。
我现在的流程时这样的,三个 http 请求都使用同一个回调函数,并传入一个接口,通过接口实现 Redis 或 MySQL 部分在查询的时候,三种不同的处理,由于返回结果的数据接口是一样的,所以返回不成问题。
后来我的上司看了之后,说我这样写不好,要我分开写,他的理由是: 1:这三个请求是不同的请求,不要统一处理。 2:这么写的话,别人看我的代码会比较麻烦。
请问,他说的对吗?能否针对他提的两个理由进行分析一下
1
rogerchen 2016-03-25 10:36:10 +08:00 via Android 1
给用户的 API 不要搞万能 API , API 的内部实现可以尽量复用相同部分。
|
2
just4test 2016-03-25 10:40:23 +08:00
一个内部的可以传入时间段的接口,再另包三个给客户端
|
3
repus911 2016-03-25 10:44:17 +08:00
老板说的对...
|
4
boydfd OP |
5
crayygy 2016-03-25 10:46:56 +08:00
API 内部实现可以使用调用某个方法去操作数据,但是对于无法看到内部实现的外部人员来说,能够直观的知道自己调用不同的 API 的用途和思路,这样会有更加清晰的逻辑。
学生党个人观点,如果有什么不足的希望能够指正!谢谢。 |
8
hitmanx 2016-03-25 10:52:20 +08:00
可以留三个回调 callback_a() callback_b() callback_c()
然后实现一个 xxx_common() callback_a()\_b()\_c()都调用这个 xxx_common() |
9
crayygy 2016-03-25 10:53:25 +08:00
@boydfd 我是这样的理解的啊不知道是不是。
Interface_A{}; Interface_B{} Interface_C{} 这三个接口是给用户调用的,在三个接口的实现里,将能够复用的代码抽象成 function(),设置不同的参数调用。这样在修改的时候可以只修改 function()的代码。 |
10
repus911 2016-03-25 11:00:49 +08:00
@boydfd 哦 如果是内部还用三个函数接口的话 那要看函数的复杂度了 值不值得重构了(比较重复的话 建议重构)
当然 作为老板提提对外的 API 的意见也就算了 为什么要管我的内部实现? 别人看我的代码,谁来看?真的看不懂?看注释懂不懂?都是不确定的问题 |
12
boydfd OP |
14
jmc891205 2016-03-25 11:17:23 +08:00
看情况而定吧。。复用当然是好的
但也不要为了复用就把可读性搞的一团糟 |
15
xuxu 2016-03-25 11:17:47 +08:00
这个看情况,上司或许看到了业务以后每个接口会不一样
|
16
boydfd OP |
17
imn1 2016-03-25 11:26:14 +08:00
大师兄说得对啊
|
18
expkzb 2016-03-25 11:32:29 +08:00
"我上司的意思是,三个不同的请求,之后调用三个函数。"
那你在这三个函数中再调用同一个函数如何呢? |
19
zhicheng 2016-03-25 11:34:17 +08:00
你知道什么叫“继承”吗?
|
20
jmc891205 2016-03-25 11:37:44 +08:00
@boydfd 定位函数是 ide 或者 editor 的功能吧
我之前见过有的人为了复用一个函数,在函数里有好多 if else 那样就不太好了 |
21
boydfd OP @expkzb 可能之前我说的有点难理解,再说清楚点,我写的是,三个请求,会调用不同的三个回调函数,在三个回调函数中,调用同一个函数。
老板的意思是,三个回调函数中不要调用相同的函数,都分开写,这样写清晰一点。 所以你的意思应该就是我之前的做法。 |
22
heqichang 2016-03-25 11:48:47 +08:00
我也不理解 callback_a()\_b()\_c()调用 a(),b(),c(),如果 a(),b(),c()都一样的话,为啥要分哩。
|
23
anerevol 2016-03-25 11:51:17 +08:00
重复的代码可以抽成函数,用组合方式减少重复。
不太清楚以后需求的变化方向,也许不同请求返回接口格式也会发生不同的变化。 |
24
JamesRuan 2016-03-25 11:59:22 +08:00
一个函数做一件事,单个函数不要超过一页。
先按这两个原则去改改看看。 Copy & Paste 永远都应该避免的,除非他们表示的其实是不同的东西,只是暂时还是相同而已,这个主要看语义。 |
25
mhycy 2016-03-25 12:12:11 +08:00
具体情况具体分析,这个只有当事人理解
注意重用代码的通用程度,如果三个函数都极其通用,那么这部分通用代码可以抽出来 不要在通用函数内部做三个事情的分别处理,如果这么做,这叫增加复杂度 另外楼上的继承其实不能乱用,不是重复代码多就一定要用继承的模式 如果编写的架构不适用于 OOP 思维,强行使用也是会增加复杂度的 剩下就自己判断吧 没贴代码我们不好判断 |
26
boydfd OP |
28
cxshun 2016-03-25 12:47:38 +08:00
方法尽量写得通用,一些比较特殊的业务由上层自己去处理,这个应该是尽量去满足的要求,在没法满足的情况下就另外想办法。
实际上你分三个方法去处理,然后调同个函数,这是没问题的啊。但感觉你可以写个大概的代码结构出来,大家会方便知道具体情况哈。 |
30
dallaslu 2016-03-25 13:31:07 +08:00
都说代码如诗,可是诗歌算是把重复用到了极至。
|
31
iniwap 2016-03-25 13:34:21 +08:00
忽然想上那张表情图
|
32
9hills 2016-03-25 13:34:59 +08:00
老板说的不对,你说的对。
本质是一个接口,输入是时间,输出是 Data ,为啥要分开。。 |
33
mengzhuo 2016-03-25 13:35:16 +08:00 via iPhone
接口和函数不是一个概念啊
接口尽量单参数甚至无参数,这样看的人就比较清楚 函数自然不重复 你老板水平有限就这么简单 |
34
phx13ye 2016-03-25 13:38:18 +08:00
你老板不懂 dry
|
35
calease 2016-03-25 13:38:25 +08:00 via iPhone
DRY 不是说代码一定不能重复。
而是代码要简明扼要。 所以 copy paste 并不一定是坏毛病, 花时间构建通用的方法也并不一定就是最好的实现方式。 很多人都有这种误区。 至于楼主的个例,没有 context 无法判定。 楼主不妨和人交流交流,对于对方的回答多问问为什么。不要别人说什么你就好的好的回头问其他人对不对。 |
36
boydfd OP @calease 我之前和老板已经讨论过,我是坚持自己这么写好,但是他只说它们是不一样的东西,就是因为他没有给我关键的理由,所以我才来这里问的啊。 copy paste 最大的坏处我就是觉得改动需要去三个地方改,不能统一进行更改,这样不仅麻烦,而且觉得会出错。
|
37
chuhemiao 2016-03-25 14:08:35 +08:00
这你能忍!
|
38
yxaaa123 2016-03-25 14:11:47 +08:00
IDEA 里直接大黄色浪线给标出来,一般人都没法忍
|
39
wuyadong 2016-03-25 14:35:06 +08:00
你是对的,但你 boss 怎么说你就按他的做。
|
40
ybh37 2016-03-25 15:31:56 +08:00
接口 必须是 3 个不同的
但是实现的时候,你可以使用一个公共函数统一处理。 你可以理解为原先一个函数,现在拆成了 4 个 |
41
quericy 2016-03-25 15:33:19 +08:00
楼主的做法:
Interface_A{ //... a(parameter_1) } Interface_B{ //... a(parameter_2) } Interface_C{ //... a(parameter_3) } a(parameter){ //Common Code } 楼主老板想要改成: Interface_A{ //... //Common Code } Interface_B{ //... //Common Code } Interface_C{ //... //Common Code } 伪代码,不知道理解是不是对的,从 dry 原则上看楼主的做法并没有错,也更利于当前的维护 但是也许老板是从需求和项目以后的可能性来考虑, "他只说它们是不一样的东西",是否意味着这以后是三个独立的业务,只是当前阶段还是相同的罢了? 所以楼主还是需要根据具体的业务上下文来判断拆分还是复用更利于以后的维护和扩展. |
43
herozzm 2016-03-25 15:54:51 +08:00
老板说的对,你还得考虑后期扩展性,比如需求以后有变动就好对照修改,别人接手也好看
|
44
secret32 2016-03-25 16:01:51 +08:00
我觉得即便以后是三个独立的业务,也应该以后再改成三个函数,现在还是用一个的好。
用三个函数对 Java 来说,只有业务独立后可以支持热部署这一点好处,然而这好处对 Go 应该等于没有。 |
46
kaizixyz 2016-03-25 16:22:48 +08:00
看得懂比方便改更重要。
|
47
xchange 2016-03-25 16:35:00 +08:00
可能老板对公司其他程序员的水平比较悲观……
|
48
holy_sin 2016-03-25 17:30:45 +08:00
不用太纠结,但是问题来了 你觉得那个号
``` if(){ xxx } if () { xxx } if () { xxx } ``` |
49
otakustay 2016-03-25 17:31:56 +08:00 1
复制粘贴下我对这种事的看法
1. 复用有很多的目的,但少写代码不应是其中一个。 2. 复用的对象是逻辑,而非代码。 3. 复用所要看的不仅仅是当下,更是未来的发展趋势是否一致。 4. 参与业务的复用,在不理解业务的前提下往往会起到反作用。 http://otakustay.com/talking-reuse/ |
50
nonesuccess 2016-03-25 17:41:27 +08:00
有重复的话,应该去除。但是这句话不等于“代码”有重复就应该去除。
应不应该去除,取决于这两段代码是不是一个东西,在你上司的眼里也许他们就不是。 说简单点,代码里面到处有 int a = 0;你会想到抽取个公共函数么? |
51
bicoff9527 2016-03-25 19:11:26 +08:00
可读性最重要吧
|
52
g00001 2016-03-25 19:34:38 +08:00
什么东西都不能绝对化,不是非此即彼,
有些时候重用的代码要封装,有些时候要避免过度设计、过度封装,以至于弄巧成拙。 有一些那种什么都封装的代码,的确看着特别恼人,写的人自己觉得很优雅,看的人觉得很笨拙。 |
53
zhaozhiming003 2016-03-25 20:59:17 +08:00
你老板很久没写代码了吧?
|
54
whenov 2016-03-25 22:21:11 +08:00
|
55
angelface 2016-03-25 22:25:31 +08:00
不上代码,谁看的明, 说的清。
|
56
qiumaoyuan 2016-03-26 09:17:21 +08:00 via iPad
只说原则:所有重复性的工作都应该教会机器,让机器来做——程序员的主要工作内容之一。
之二是尽量让其他人更加容易地知道你对机器都说了些什么。 没有了。 所以,不让你去除重复,是错的。问题是如何去除重复,而不是要不要消除重复。 “消除重复”和“代码易读”并没有矛盾,用你所使用的编程语言特性——比如面向对象——找到这两件事的平衡点。 我总是觉得,新手没有底线的追求消除重复是很有必要,很有好处的。但是过程中遇到问题要想办法解决,而不是偷懒,选择认为此路不通。 |