Java 业务开发常见错误 100 例
朱晔
贝壳金服资深架构师
52944 人已学习
新⼈⾸单¥59
登录后,你可以任选4讲全文学习
课程目录
已完结/共 48 讲
代码篇 (23讲)
Java 业务开发常见错误 100 例
15
15
1.0x
00:00/00:00
登录|注册

21 | 代码重复:搞定代码重复的三个绝招

思考与讨论
属性拷贝工具
注解+反射
模板方法模式
代码重复消除方法总结

该思维导图由 AI 生成,仅供参考

你好,我是朱晔。今天,我来和你聊聊搞定代码重复的三个绝招。
业务同学抱怨业务开发没有技术含量,用不到设计模式、Java 高级特性、OOP,平时写代码都在堆 CRUD,个人成长无从谈起。每次面试官问到“请说说平时常用的设计模式”,都只能答单例模式,因为其他设计模式的确是听过但没用过;对于反射、注解之类的高级特性,也只是知道它们在写框架的时候非常常用,但自己又不写框架代码,没有用武之地。
其实,我认为不是这样的。设计模式、OOP 是前辈们在大型项目中积累下来的经验,通过这些方法论来改善大型项目的可维护性。反射、注解、泛型等高级特性在框架中大量使用的原因是,框架往往需要以同一套算法来应对不同的数据结构,而这些特性可以帮助减少重复代码,提升项目可维护性。
在我看来,可维护性是大型项目成熟度的一个重要指标,而提升可维护性非常重要的一个手段就是减少代码重复。那为什么这样说呢?
如果多处重复代码实现完全相同的功能,很容易修改一处忘记修改另一处,造成 Bug;
有一些代码并不是完全重复,而是相似度很高,修改这些类似的代码容易改(复制粘贴)错,把原本有区别的地方改为了一样。
今天,我就从业务代码中最常见的三个需求展开,和你聊聊如何使用 Java 中的一些高级特性、设计模式,以及一些工具消除重复代码,才能既优雅又高端。通过今天的学习,也希望改变你对业务代码没有技术含量的看法。
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

本文介绍了如何利用注解和反射技术来消除重复代码,以及如何将业务逻辑实现为面向对象的方式。通过银行API接口调用案例,作者展示了如何使用自定义注解和反射来描述接口参数和动态组装参数,从而避免重复的参数处理逻辑。文章通过示例代码详细解释了如何利用注解为接口和参数增加元数据,以及如何使用反射实现动态的接口参数组装和请求调用。通过这种方式,读者可以学习到如何利用注解和反射来实现通用逻辑,从而减少重复代码,提高代码的可维护性和可扩展性。这种技术不仅能够帮助读者更好地理解面向对象编程的思想,还能够在实际项目中提升代码的质量和可维护性。文章内容详实,适合对Java高级特性和设计模式感兴趣的读者学习参考。文章还提到了如何利用Bean属性复制工具消除重复代码,以及如何使用模板方法设计模式和观察者模式来减少代码重复。同时,作者强调了消除重复代码对项目质量的重要性,以及在项目重构中以消除重复为第一目标的重要性。整体而言,本文为读者提供了丰富的技术知识和实践经验,对于提高代码质量和减少重复代码具有重要的指导意义。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《Java 业务开发常见错误 100 例》
新⼈⾸单¥59
立即购买
登录 后留言

全部留言(48)

  • 最新
  • 精选
  • Asura
    置顶
    写得真好 想问下项目里用到不同设计模式 类的命名规范 以及放置这些设计模式的包的命名规范是怎么样的

    作者回复: 包名没有规范,涉及到设计模式类名可以以 Locker Iterator Extractor Accessor Validator Formatter Converter Replacer Comparer Manager Combiner Parser Encoder Decoder Importer Exporter Editor Modifier Evaluator Locator Creator Initializer Reader Writer Activator Finder Builder Selector Visitor Loader Descriptor Generator Adapter Listener Wrapper Mapper Binder Invoker Executor Detector Tracer Decorator Mapper Resolver Processor Advisor Dispatcher Consumer Producer Publisher Subscriber Handler Filter Interceptor Provider Container 单词作为前后缀 以提现类作用或者模式

    2020-05-14
    4
    102
  • 待时而发
    置顶
    太实用了 老师。我还真的在日常开发中碰到过太多您所提到的这些问题了,而且很多

    作者回复: 有收获就好

    2020-05-02
    25
  • Darren
    一、观察者模式的在Spring中的使用:spring listener就是基于观察者模式的:主要是三个组件: 1. 事件,需要继承ApplicationEvent,即观察者模式中的"主题",可以看做一个普通的bean类,用于保存在listener的业务逻辑中需要的一些字段; 2. 事件listener,需要实现ApplicationListener<E extends ApplicationEvent>,即观察者模式中的"观察者",在主题发生变化时收到通知,并作出相应的更新,加泛型表示只listen某种类型的事件; 3. 事件发布器,需要实现ApplicationEventPublisherAware,获取spring底层组件ApplicationEventPublisher,并调用其方法发布事件,即"通知"观察者。 二、Bean 属性复制,原理肯定是反射了,其实自己实现也很简单,或者反射或者内省,内省实现最简单,以前使用内省实现过。现在主要是用hutool,超级好用的工具包,里面基本你想要的工具类都有,欢迎大家使用https://hutool.cn/

    作者回复: 感谢分享

    2020-05-05
    3
    43
  • cky.宇
    十分感谢老师的分享,感觉干货十足,收获很多。 这里补充一个项目也经常用到的策略模式,以老师的银行数值格式化的代码为例: switch (bankAPIField.type()) { case "S": { stringBuilder.append(String.format("%-" + bankAPIField.length() + "s", value.toString()).replace(' ', '_')); break; } // ... } 可以转为基于枚举的策略模式 enum BankAPIFieldType { S { @Override public String format(Object value, BankAPIField bankAPIField) { return String.format("%-" + bankAPIField.length() + "s", value.toString()).replace(' ', '_'); } }, // ... ; public abstract String format(Object value, BankAPIField bankAPIField); } 将BankAPIField的type类型限制为BankAPIFieldType public @interface BankAPIField { int order() default -1; int length() default -1; BankAPIFieldType type() default BankAPIFieldType.DEFAULT; } 然后调用的时候就可以简化为: stringBuilder.append(bankAPIField.type().format(value, bankAPIField)); 这样做一个是可以限制type的值范围,防止传入的string错误。另一个是减少了主干逻辑的代码,会更清晰点。

    作者回复: 不错

    2020-08-15
    5
    25
  • Jerry Wu
    这篇文章、demo值得看几十几百遍,感觉打通了任督二脉。 以前学过设计模式、Java的高级特性,但只能算看过,完全不知道怎么用在工作。 看完这篇文章才发现,代码还能这样写。刚好,公司有一大堆乱七八糟的代码,实践的时候到了。

    作者回复: :)

    2020-05-07
    4
    19
  • 👽
    购物车的例子,我个人理解,Java8中,可以使用接口以及default来代替抽象类。我认为使用接口更好,因为接口可以多实现,但是抽象类不可多继承。

    作者回复: 也不能完全替代,抽象类可以有状态,而且接口语义上是can-do,抽象类是is-a,还是选择更符合语义的方式来实现比较好

    2020-05-12
    2
    16
  • Sky1225
    BeanUtils不推荐使用,这个工具是在运行时转换的,遇到同名不同类型的字段不会转换,而且没有错误提示,可能会有坑,推荐使用mapstruct,这个是在编译器生成转换代码,对于普通类型会自动转换(如int和String),对于不能自动转换的会有错误提示,且能看到生成的代码

    作者回复: 没错 答疑中我也提到

    2021-07-30
    7
  • 程序员小跃
    开篇这些问题,不就是我遇到的问题吗,老师来的太及时了。今天还和朋友聊到设计模式的辩论,有用还是无用,看了这篇文章,我心里又有底了。优秀程序员进阶,走起

    作者回复: 奥利给

    2020-07-24
    7
  • FelixFly
    1. 松耦合的方式一般都是用于消息发送,比如说短信发送、日志推送等等,消息队列是分布式中的松耦合 2. Bean 属性复制:https://www.jianshu.com/p/40e0e64797b9 这篇文章基本全了

    作者回复: 感谢分享

    2020-05-12
    5
  • insight
    想问一下老师,属性拷贝工具相较于直接写get和set,会有性能上的差异嘛?

    作者回复: 会有 不过一般不会存在性能瓶颈

    2020-05-02
    3
    4
收起评论
显示
设置
留言
48
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部