RT, Java 代码,一个方法中,逻辑特别多,于是把里面逻辑封装成了几个单独方法,但是也有七八个单独方法,看起来也有点难受:
fun() { fun1(); // 数据初始化 // 这里有几行代码,处理特殊逻辑 fun2(); fun3(); // 调用第三方 fun4(); // 这里有打印日志 fun5(); // 缓存处理 fun6(); // 这里有一些代码,做对象转换等 fun7(); // 打印日志等 fun8(); // 缓存处理 return xxx; }
感觉还是在面向过程去写,有点难受看着,但是有没有优化思路,或者优秀代码参考。
![]() | 1 cmdOptionKana 2021-08-16 18:44:41 +08:00 先建模型啊,单单给出正文里这些信息并不足够,你要看看你处理的对象是什么,是用户、商品、文章、图形还是别的什么东西,要先找到对象才能面向对象。 |
2 Rwing 2021-08-16 18:46:42 +08:00 确实是面向过程,你要抽象一下 然后缓存可以抽出来,日志可以抽出来 如果可以你可以贴出具体代码 |
![]() | 3 cmdOptionKana 2021-08-16 18:47:29 +08:00 找到对象后,就看对象有哪些属性、哪些行为,比如商品有属性“价格”、“分类”,有行为“被预定”、“被销售”等。 文章有属性“标题”、“发布时间”,有行为“被创建”、“被发布”等。 |
4 misdake 2021-08-16 18:57:04 +08:00 ![]() 想到一篇很老的文章,有点无关又有点相关,我贴一下标题和链接。很老的文章,背景也比较复杂,仅供参考。 John Carmack on Inlined Code http://number-none.com/blow/john_carmack_on_inlined_code.html |
![]() | 5 CEBBCAT 2021-08-16 19:59:02 +08:00 在我看来,这些逻辑它们本来就是面向过程的,因此你无法通过抽象代码来让代码更优雅。 不过,可不可以通过 MQ 等,把这些逻辑分开来写呢?我想这是一种有效的解决办法,也是符合直觉和逻辑的 |
6 mxT52CRuqR6o5 2021-08-16 20:05:15 +08:00 (如果是 spring 大概会是下面这种思路?) 数据操作,每张表一个类 每个第三方的所有操作一个类 日志一个类 缓存一个类 最后一起依赖注入进来 |
7 mxT52CRuqR6o5 2021-08-16 20:10:01 +08:00 我看着感觉日志啊缓存啊转换啊,可能有方法去优化掉,就比如日志和缓存有没有什么固定的逻辑,就能抽象出来 就比如做同一类操作的时候会固定记录日志,那你直接把记录日志的代码放到做这一类操作继承的 class 中去,就不用先调一遍这一类的方法,再手动去记日志 |
8 auh 2021-08-16 20:22:57 +08:00 这些操作具备对象的特征?个人感觉只能具备业务逻辑的特征。不管是不是面向对象。最后肯定有一个组合逻辑的过程。组合逻辑过程,就像 @misdake 引用的文章类似,采用哪种风格,来管理使得更加灵活或者更加封闭。就算是各个 func 归类到不同的对象中,这个组合过程,还是类似这种逻辑。充其量抽象成接口,能够灵活替换一下。 |
9 wangxiaoaer 2021-08-16 20:57:56 +08:00 某些 fun 是否提取成对象单独处理,把这个 fun 里面的逻辑交由那个对象负责,也就是 fun()----> anotherObj.fun() |
![]() | 10 TypeError 2021-08-16 21:05:15 +08:00 分层加上拆分模块吧 |
![]() | 11 Kasumi20 2021-08-16 22:44:59 +08:00 日志用 AOP, 面向切面编程 |
12 felixin 2021-08-16 22:55:05 +08:00 via Android 学习 clean code |
13 ljzxloaf 2021-08-16 23:04:11 +08:00 需要换个角度去思考问题。 打个比方,产品需求描述一般是用户场景和交互流程,而这些变化是非常快的,我们不可能给每个场景、每个流程写一套代码,所以需要从业务模型的角度去思考,而不能从业务流程的角度去思考。比如你这种就可以看做是几种业务模型组合起来的流程,其中的业务模型有第三方业务、缓存、日志等,我认为你这种写法没啥问题。如果有些逻辑重复读较高,可以根据业务更为细致的封装。比如 A 业务与 B 业务组合起来形成一个业务。这种组合就看具体需求了。 流程与对象是相对的,流程的每个节点都是对象,对象的内部逻辑也是流程。 实践中,我们一般可以同时提供两种接口:一种是不依赖其他业务的“原子”接口;另一种是依赖其他业务的“组合”接口。 比如搜索,我可以同时提供:返回 id 集合的接口和返回 item 集合的接口。item 信息是我从 item 服务拿到的,这样我等于组合了 item 服务和搜索。反过来也类似,比如敏感内容过滤,我也可以提供两种接口:传参 id 集合和传参 item 集合,如果只传 id 我需要去 item 服务查 item 信息,就是组合接口;如果传给我 item 集合,我就不需要去依赖 item 服务。 这种做法有什么好处呢?我们可以先考虑这样一个问题,我们有底层服务 A ( atom ),有两个上层服务 C1 、C2 ( combination ),现在有个需求要调用 C1 的接口 C1.I1 和 C2 的接口 C2.I1 ,这两个接口都要调用 A 的接口 A1.I1 ,这样我们为何不先调 A1.I1 ,然后把返回的信息传给 C1 和 C2 呢?当然当我们没有这种冗余调用的时候,还是用原来的接口,这样更方便。 我分析下来这样做从性能方面应该是有利无害的。从 IO 方面来看,虽然直接传递 item 信息增加了传递参数的网络开销,但是由于不需要去查 item 服务,减少了一次 item 服务返回 item 信息的网络开销,这两者已经抵消了。而后者还减少了查 item 的请求网络开销,item 服务的计算开销,和依赖服务或 db 的计算和网络开销。所以性能无疑是提高了很多。 上面只讨论了最简单的情况,其实实践中远比这复杂。上层服务会依赖多个下层服务,组合是千变万化的,不可能为每种组合都开个接口。比如 C 依赖 A1 和 A2,那就要四个接口,依赖 A1 的接口( A2 信息通过传参);依赖 A2 的接口( A1 信息通过传参);都不依赖(全部信息通过传参);都依赖。假设依赖 n 个服务,就需要(排列组合 n 选 n 、n-1...1,0 加和)个接口(感觉像科里化过程...),所以还是要根据实际情况具体问题具体分析,只提供那些用户普遍需要的组合。 |
![]() | 14 sutra 2021-08-17 00:05:53 +08:00 非业务相关的逻辑都可以从这个方法里移除。 比如缓存处理,就可以放到应该被缓存的对象的服务层那里,并通过 annotation,比如 @CacheResult/@Cachable 这类 spring-cache 的注解来完成。 对象转换,可以通过代码分层到专门做对象转换的类里,比如像他这样: https://juejin.cn/post/6844903685860884488 |
15 jorneyr 2021-08-17 09:04:44 +08:00 如果是业务代码,且重复出现的次数没有,就这么写,不要优化,否则优化后连自己都不认识了、 |
![]() | 16 aliveyang 2021-08-17 09:12:08 +08:00 不只是优化代码,还要优化业务 |
![]() | 18 litchinn 2021-08-17 10:26:14 +08:00 ![]() 观察者模式之事件编程之 spring event,可以试下 |
![]() | 19 CasualYours 2021-08-17 10:48:31 +08:00 我之前曾经尝试把业务逻辑实现改为链式调用的形式,看上去是舒服了一点。 TaskWrapperProvider.init(wrapperMapper).createWrapper(taskId).signIn(signParams); // 任务签到的需求 |
![]() | 20 masterclock 2021-08-17 10:50:43 +08:00 从上到下,没有分支,应该是最完美的代码了,仅次于没有代码。 最大的问题是写不出这样的代码 - 业务流程会变化 - 业务流程会失败 - 非业务流程的代码也会失败 - 到处都有可能失败 - …… 然后就可以考虑架构设计,代码抽象等来解决问题了 |
21 dqzcwxb 2021-08-17 11:24:28 +08:00 思维导图 沟通 spring event lambda stream optional extract method |
22 cutepig 2021-08-17 13:19:13 +08:00 via Android 最近在看函式程, 感如果你拆分的子函 func1,。。。能到函式的那种重用性,那麽感会很不一样 |
23 DICK23 2021-08-18 14:00:36 +08:00 用 AOP 去搞? |
24 securityCoding 2021-08-18 16:15:44 +08:00 既然存在上下文关系,考虑定义一个 filter 接口来隔离各个功能实现吧 |
![]() | 25 funbox 2021-08-19 10:51:58 +08:00 把业务逻辑代码写那么复杂 别人砍你 |