设计模式+代码重构实战
文章平均质量分 85
设计模式+代码重构实战
JavaEdge.
关注并私信我,获取更多大厂求职经验。《编程严选网》创始人
展开
-
软件设计原则(02)-开闭原则(Open Close Principle,OCP)
来个需求就改一次代码,理所当然?反正修改也易,再CV一份,也不费脑。但每人每次改点,日积月累,再来新需求,后人改动量就大了。每人都无辜,都只是简单修改一点。但最终导致接盘侠无法维护,直接推翻老系统,写新系统(也算是创造就业机会了)。既然“修改”这么多问题,不修改行吗?就得精通OCP。一个软件实体如类、模块和方法应对扩展开放,对修改关闭。原创 2023-09-13 10:15:49 · 136 阅读 · 0 评论 -
火车残骸和基本类型偏执问题解决方案
过长的消息链,或者叫火车残骸基本类型偏执。火车残骸的代码就是连续的函数调用,它反映的问题就是把实现细节暴露了出去,缺乏应有的封装。重构的手法是隐藏委托关系,实际就是做封装。软件行业有一个编程指导原则,叫迪米特法则,可以作为日常工作的指导,规避这种坏味道的出现。基本类型偏执就是用各种基本类型作为模型到处传递,这种情况下通常是缺少了一个模型。解决它,常用的重构手法是以对象取代基本类型,也就是提供一个模型代替原来的基本类型。原创 2023-01-23 01:37:29 · 582 阅读 · 1 评论 -
软件设计到底是什么?
模型,是一个软件的骨架,是一个软件之所以是这个软件的核心。模型的粒度可大可小。我们所说的“高内聚、低耦合”指的就是对模型的要求,一个好的模型可以有效地隐藏细节,让开发者易于理解。模型是分层的,可以不断地叠加,基于一个基础的模型去构建上一层的模型,计算机世界就是这样一点点构建出来的。规范,就是限定了什么样的需求应该以怎样的方式去完成。它对于维系软件长期演化至关重要。关于规范,常见的两种问题是:一个项目缺乏显式的、统一的规范;规范不符合软件设计原则。原创 2023-01-21 13:58:16 · 1837 阅读 · 0 评论 -
如何了解一个软件的设计?
模型,也称为抽象,软件核心部分,该系统与其它系统有所区别的关键接口,通过怎样方式将模型提供的能力暴露,是我们与这个软件交互的入口实现,就是软件提供的模型和接口在内部是如何实现的,是软件能力得以发挥的根基了解设计的顺序:模型=》接口=》实现。了解设计,需要一层一层地展开,在每个层次都按照模型、接口和实现进行理解,在头脑中形成一棵设计树。了解设计,先模型,再接口,最后是实现。原创 2023-01-17 17:36:29 · 4735 阅读 · 13 评论 -
我只会 Java 一门语言可以吗?
面向对象用来组织程序是好,但我用的是C语言;我用的是C++,函数式编程的好,跟我有什么关系;动态语言那些特性很好,可惜我用的Java;……如果你这么想,说明你被自己的看家本事给局限住了,这种思维方式会让你即便学到了更多好东西,也无可奈何。程序设计语言之间没有那么泾渭分明的界限,唯有多学几门,才能打破语言局限,让设计更好落地。可根据项目特点选择合适语言,也可以将其它语言一些优秀的地方借鉴过来。Andrew Hunt和David Thomas在《程序员修炼之道》(The Pragmatic Prog原创 2023-01-15 03:34:07 · 8194 阅读 · 7 评论 -
大厂怎么做Code Review?
对于大部分人,CR只是一个发现问题的过程,本文讨论的是CR是一个沟通反馈的过程。站在沟通反馈的角度,尽可能多地暴露问题,尽可能多地做CR。CR可以从实现方案正确性、算法正确性和代码坏味道的角度去发现问题。CR的频率是越高越好,频率越高,发现和解决问题的难度越低,团队越容易坚持下去。如果把CR推向极致就是随时随地做CR,就是结对编程。CR暴露的问题越多越好,频率越高越好。原创 2023-01-14 22:44:50 · 1966 阅读 · 0 评论 -
过度设计有意义吗
看着自己每次根据设计原则及模式的代码重构,虽效果不错,但也自省:如果我的每段代码都这么写,是不是过度设计?把握设计的度,需长久锤炼。做了更多的功能,并不会得到更多的回报,但是,做了更多的功能,软件本身却会不断地膨胀,越难维护。怎么知道系统按照预期工作,就需要有配套自动化测试,最好能TDD,最根本的还是要懂设计,否则,你的代码就是不可测。不懂设计,重构就只是简单提取方法,改改名字,对代码的改进相当有限。让类和方法的数量最小化,不要过度设计,除非你已看到这必须要做个设计,比如,留下适当扩展点,否则,就不要做。原创 2023-01-14 17:12:28 · 315 阅读 · 0 评论 -
使用Java为何总写出C风格的代码?
编程范式指的是程序的编写模式。编程范式对程序员的能力施加了约束,理解编程范式的一个关键点在于,哪些事情不要做。编程范式与具体语言的关系不大,但很多语言都有着自己主流的编程范式。但现在的一个趋势是,打破编程范式的“次元壁”,把不同编程范式中优秀的元素放在一起。可以通过设计,模拟出其他编程范式中的元素程序设计语言的发展趋势也是要融合不同编程范式中优秀的元素学习不同的编程范式,已经成为每个程序员的必修课。学习不同的编程范式,将其中优秀的元素运用在日常工作中。原创 2023-01-14 06:26:34 · 5242 阅读 · 1 评论 -
继承是代码复用的最佳方案吗?
组合优于继承。复用方式背后的编程思想:面向组合编程。它给我们提供了一个不同的视角,但支撑面向组合编程的是分离关注点。将不同关注点分离,每个关注点成为一个模块,在需要时组装。面向组合编程,在设计本身上有很多优秀地方,可降低程序复杂度,更是思维转变。参考。原创 2023-01-14 03:42:58 · 2988 阅读 · 0 评论 -
set 方法是坏味道?
程序=数据结构+算法,所以,数据几乎是软件开发最核心的一个组成部分。在一些人的认知中,所谓做软件,就是一系列的 CRUD 操作,也就是对数据进行增删改查。再具体一点,写代码就把各种数据拿来,然后改来改去。我们学习编程时,首先学会的,也是给变量赋值,类似 a = b + 1。改数据,几乎已经成了很多程序员写代码的标准做法。然而,这种做法也带来了很多的问题。满天飞的 Setterpublic void approve(final long bookId) { ... book.setReviewS原创 2023-01-12 01:47:54 · 4255 阅读 · 0 评论 -
接口隔离原则:接口里的方法,你都用得到吗?
不应强迫使用者依赖于它们不需要的方法。因为很多接口都设计得包含了太多内容。更好的设计是把大接口分解成一个个小接口。这里的接口不仅是一种语法,所有的public方法都是接口。我们在做接口设计时,需要关注不同的使用者。我们可以把ISP理解成接口设计的SRP。每个使用者面对的接口,其实都是一种角色接口。识别出接口不同的角色是至关重要的,这也与分离关注点的能力是相关的。ISP还可以从更广泛的角度去理解,也就是说,不要依赖于任何不需要的东西,这个原则可以指导我们在高层次上进行设计。原创 2023-01-11 00:32:27 · 840 阅读 · 0 评论 -
接到新需求时,从何开始设计?
即便我们能够极尽所能把代码写整洁,规避各种坏味道,但我们小心翼翼维护的代码,还是可能因为新的需求被破坏。新的需求总会在路上,所以,写代码时需要时时刻刻保持嗅觉。这一讲加餐,我来给你讲讲两个发生在真实项目中的故事。一次驳回的实现有个功能,内容作品提交之后要由相应的编辑审核。审核有审核通过和不通过,这是系统中早就开发完成的。有一天,新的需求来了:驳回审核通过的章节,让作者重新修改。造成作品需要驳回的原因有很多,比如,审核标准的调整,这就会导致原先通过审核的作品又变得不合格。先看代码库已有怎样的基础原创 2023-01-11 00:31:13 · 446 阅读 · 0 评论 -
阿里资深工程师教你门面模式
类、模块、系统之间的“通信”,一般都是通过接口调用。接口设计的好坏,直接影响到类、模块、系统是否好用。完成接口设计,就相当于完成了一半的开发任务。只要接口设计得好,那代码就不会太差。太大会导致接口不可复用太小会导致接口不易用接口可复用性和易用性需要权衡,基本处理原则:尽量保持接口的可复用性,但针对特殊情况,允许提供冗余的门面接口,来提供更易用的接口。原创 2022-12-20 01:47:10 · 380 阅读 · 1 评论 -
一文讲明生产者-消费者模式
生产者-消费者模式的优点核心是一个任务队列,生产者线程生产任务,并将任务添加到任务队列中,而消费者线程从任务队列中获取任务并执行。解耦解耦的一个关键就是组件之间的依赖关系和通信方式必须受限。在生产者-消费者模式中,生产者和消费者没有任何依赖关系,它们彼此之间的通信只能通过任务队列,所以生产者-消费者模式是一个不错的解耦方案。异步平衡生产者和消费者的速度差异。生产者线程只需要将任务添加到任务队列,无需等待任务被消费者线程执行完,即任务的生产和消费是异步的。异步化处理最简单的方式就是创建一个新的线程原创 2021-05-24 10:20:00 · 2385 阅读 · 7 评论 -
代码重构实战-将值对象改为引用对象(Change Value to Reference)
动机一个数据结构中可能包含多个记录,而这些记录都关联到同一个逻辑数据结构。例如,我可能会读取一系列订单数据,其中有多条订单属于同一个顾客。遇到这样的共享关系,既能将顾客信息作为值对象看待,也能将其视为引用对象:若将其视为值对象,则每份订单数据中都会复制顾客的数据若将其视为引用对象,对于一个顾客,就只有一份数据结构,会有多个订单与之关联若顾客数据永不修改,则两种方式都合理。 把同一份数据复制多次可能会造成一点困扰,但这种情况也很常见,不是太大问题。过多的数据复制有可能会造成内存占用的问题,但就跟原创 2022-04-01 21:29:29 · 1078 阅读 · 1 评论 -
祖传shi山代码重构实战(01)-Extract Class提炼类
某个类做了应该由两个类做的事。建立一个新类,将相关的字段和函数从旧类移到新类。动机一个类应该是一个清楚的抽象,处理一些明确的责任。但实际工作中,类会不断扩展。你会在这儿加入一些功能,在那儿加入一些数据。给某个类添加一项新责任时,你会觉得不值得为这项责任分离出一个单独的类。于是,随着责任不断增加,这个类会变得过分复杂。很快,你的类变成一团乱麻。这样的类往往含有大量函数和数据,太大而不易理解。此时你需要考虑哪些部分可以分离出去,并将它们分离到一个单独的类。如果某些数据和某些函数总是一起出现,某些数据经原创 2022-03-31 18:52:48 · 1262 阅读 · 0 评论 -
Java编程思想第五版(On Java8)(四)-运算符
文章目录开始使用优先级赋值方法调用中的别名现象算术运算符一元加减运算符递增和递减关系运算符测试对象等价逻辑运算符短路字面值常量下划线指数计数法位运算符移位运算符三元运算符字符串运算符常见陷阱类型转换截断和舍入类型提升Java没有sizeof运算符总结本章小结运算符操纵数据。Java 是从 C++ 的基础上做了一些改进和简化发展而成的。对于 C/C++ 程序员来说,Java 的运算符并不陌...原创 2020-04-11 17:42:20 · 1779 阅读 · 0 评论 -
Java 编程思想第十二章 - 容器持有对象
文章目录1 泛型和类型安全的集合泛型下的向上转型2 基本概念3 添加元素组4 打印集合默认的打印5 List6 迭代器IteratorsListIterator链表LinkedList如果一个程序只包含固定数量的对象且对象的生命周期都是已知的,那么这是一个非常简单的程序。编程痛点通常程序总是根据运行时才知道某些条件,从而去创建新的对象。在此之前,无法知道所需对象的数量甚至确切类型。解决方案需要在任意时刻和任意位置创建任意数量的对象。因此,不能再简单地这样依靠创建命名的引用来持有每一个对象:原创 2020-05-24 22:38:02 · 1607 阅读 · 1 评论 -
Java异常机制的最佳实践
文章目录1 异常概念1.1 历史中所谓的“异常”解决方案2 基本异常简单的例子抛出异常后抛出异常的简单例子异常模型的观点异常参数3 异常捕获3.1 try 块意义3.2 异常处理程序 - catch 块意义3.3 终止与恢复3.3.1 终止模型3.3.2 恢复模型缺陷4 自定义异常无参构造器字符串参数的构造器4.1 记录日志捕获和记录其他人编写的异常加入额外构造器和成员5 异常声明“作弊”的地方6 捕获所有异常多重捕获栈轨迹重新抛出异常精准的重新抛出异常异常链Java 标准异常特例:RuntimeExcep原创 2020-06-01 09:09:56 · 1843 阅读 · 0 评论 -
Java编程思想精粹(On Java8)(十)-接口
接口和抽象类提供了一种将接口与实现分离的更加结构化的方法。这种机制在编程语言中并不常见C++ 只对这种概念提供间接支持Java 为它们提供了直接支持 - 关键字尽管你的第一想法是创建接口,但对于构建具有属性和未实现方法的类来说,抽象类也是重要且必要的工具。你不可能总是使用纯粹的接口。1 抽象类创建通用接口的唯一理由是,不同的子类可以用不同的方式表示此接口。通用接口建立了一个基本形式,以此表达所有派生类的共同部分。有时把 Instrument 称为抽象基类,或简称抽象类。对于抽象类,它的原创 2020-05-17 21:30:13 · 1902 阅读 · 0 评论 -
彻底讲清 Java 的泛型(上)
普通的类和方法只能使用特定的类型:基本数据类型或类类型。如果编写的代码需要应用于多种类型,这种严苛的限制对代码的束缚就会很大。多态是一种面向对象思想的泛化机制。可以将方法的参数类型设为基类,这样的方法就可以接受任何派生类作为参数,包括暂时还不存在的类。这样的方法更通用,应用范围更广。在类内部也是如此,在任何使用特定类型的地方,基类意味着更大的灵活性。除了 final 类(或只提供私有构造函数的类)任何类型都可被扩展,所以大部分时候这种灵活性是自带的。接口可以突破继承体系的限制单一的继.原创 2020-06-26 04:35:54 · 2022 阅读 · 4 评论 -
深入解析Java的注解机制
目录1 基本语法1.1 定义注解1.2 元注解编写注解处理器注解元素默认值限制生成外部文件替代方案注解不支持继承实现处理器使用javac处理注解最简单的处理器更复杂的处理器基于注解的单元测试在 @Unit 中使用泛型实现 @Unit本章小结注解(也被称为元数据)为我们在代码中添加信息提供了一种形式化的方式,使我们可以在稍后的某个时刻更容易的使用这些数据。注解在一定程度上是把元数据和源代码文件结合在一起的趋势所激发的,而不是保存在外部文档。这同样是对像 C# 语言对于 Java 语言特性压力的一种回应翻译 2020-07-11 21:54:19 · 1668 阅读 · 1 评论 -
Java编程思想第五版(On Java8)(二十四)-并发编程
文章目录第二十四章 并发编程术语问题并发的新定义并发的超能力并发为速度而生四句格言1.不要这样做2.没有什么是真的,一切可能都有问题3.它起作用,并不意味着它没有问题4.你必须仍然理解残酷的真相本章其余部分并行流创建和运行任务终止耗时任务CompletableFuture类基本用法结合CompletableFutures模拟例外情况流异常检查异常死锁构造函数非线程安全复杂性和代价本章小结缺点共享内...原创 2020-04-13 16:38:16 · 3528 阅读 · 3 评论 -
深度解析 Java 的 Optional 类
使用内置的 null 来表示没有对象,每次使用引用的时候就必须测试一下引用是否为 null,这显得有点枯燥,而且势必会产生相当乏味的代码。null 没啥行为,只会产生 NullPointException。java.util.Optional为 null 值提供了一个轻量级代理,Optional 对象可以防止你的代码抛 NullPointException。虽然 Optional 是 Java 8 为了支持流式编程才引入的,但其实它是一个通用的工具。实际上,在所有地方都使用 Optional 是没有意原创 2020-06-26 00:21:36 · 1798 阅读 · 2 评论 -
Java 反射最终篇 - Mock 对象和桩
Mock 对象和 **桩(Stub)**在逻辑上都是 Optional 的变体。他们都是最终程序中所使用的“实际”对象的代理。不过,Mock 对象和桩都是假扮成那些可以传递实际信息的实际对象,而不是像 Optional 那样把包含潜在 null 值的对象隐藏。Mock 对象和桩之间的的差别在于程度不同。Mock 对象往往是轻量级的,且用于自测试。通常,为了处理各种不同的测试场景,我们会创建出很多 Mock 对象。桩只是返回桩数据,通常是重量级的,在多个测试中被复用。可以根据它们被调用的方式,通过配原创 2020-06-26 03:51:42 · 2845 阅读 · 0 评论 -
Java8编程思想精粹(十一)-内部类
文章目录创建内部类链接外部类使用 .this 和 .new内部类与向上转型内部类方法和作用域匿名内部类嵌套类接口内部的类从多层嵌套类中访问外部类的成员为什么需要内部类闭包与回调内部类与控制框架继承内部类内部类可以被覆盖么?局部内部类内部类标识符本章小结一个定义在另一个类中的类,叫作内部类。内部类是一种非常有用的特性,因为它允许你把一些逻辑相关的类组织在一起,并控制位于内部的类的可见性。然而必须要了解,内部类与组合是完全不同的概念,这一点很重要。在最初,内部类看起来就像是一种代码隐藏机制:将类置于其他原创 2020-05-17 16:28:29 · 1723 阅读 · 0 评论 -
Java 的线程工厂 ThreadFactory原理及源码详解
在JDK的源码使用工厂模式,ThreadFactory就是其中一种。在我们一般的使用中,创建一个线程,通常有两种方式:继承Thread类,覆盖run方法,实现我们需要的业务继承Runnable接口,实现run方法,实现我们需要的业务,并且调用new Thread(Runnable)方法,将其包装为一个线程执行设想这样一种场景,我们需要一个线程池,并且对于线程池中的线程对象,赋予统一的线程优...原创 2020-03-08 14:12:47 · 5051 阅读 · 1 评论 -
OOP三大特性之封装
结构化编程有效解决了很多问题,但随代码膨胀,结构化编程的局限也越发凸显。但它提供的解决方案中,各模块依赖关系太强,不能有效将变化隔离。于是,OOP诞生,提供更好的程序组织方案。习惯结构化编程的程序员,认为OO就是数据+函数。这种理解不算全错,但理解程度太低。结构化编程思维就如用显微镜看世界,这只能看到局部。而想要用好OOP,则需有更宏观的视角。我们都知道 OOP三大特点:封装、继承和多态。虽然背的都挺熟练,面试时都知道,但实际上,我看很多程序员的代码风格,还真没理解这三大特点。面试时说的头头是原创 2021-10-06 01:51:25 · 1478 阅读 · 4 评论 -
《代码重构》之方法到底多长算“长”?
我们知道程序员都必须用大屏显示器,而且还要竖起来,才能看全一个方法!只要一提到长函数:被迫理解一个长函数在一个长函数中,小心翼翼地找出需要的逻辑,按需求微调几乎所有程序员都会有类似经历。没人喜欢长函数,但你却要一直和各种长函数打交道。几百上千行的函数肯定是不足以称霸的。多长的函数才算“长”?100 行?对于函数长度容忍度太高了!这是导致长函数产生的关键点。看具体代码时,一定要能够看到细微之处。关键点就是将任务拆解得越小越好,这个观点对代码同样适用。随着对代码长度容忍度的降低,对代码细节原创 2021-09-26 15:59:34 · 1834 阅读 · 5 评论 -
阿里华为等大厂架构师如何解决空指针问题
Java的null 表示它没有引用指向或没有指针,这时操作该变量必会引发空指针异常,即NullPointerException。当线上环境发生该异常时,就会收到大量投诉!如何才能避免呢?毕竟NPE虽烦人但易定位,麻烦的是要弄清楚null含义。客户端给服务端一个null,其本意就是想给个空值,还是根本没提供值?DB字段的NULL值,是否有特殊含义?针对DB的NULL值,写SQL需要特注意啥呢?根据开发经验,NPE出现场景可归结如下场景:参数是Integer等包装类,自动拆箱时字符串比较如C原创 2020-12-29 21:02:45 · 1403 阅读 · 1 评论 -
私有构造方法强制不可实例化的性质
有时想编写只有静态方法和静态字段的类。这种类很不好,因为有些人滥用在OOP 语言编写面向过程的程序,但确有用途。可用 java.lang.Math 或 java.util.Arrays 这种类,把基本类型的值或数组类型的方法组织起来。还可以用于对以 java.util.Collections 的方式,把实现特定接口的对象上的静态方法组织起来。( Java 8,可以将这些方法放入接口中,假设是你自己编写的可以修改)。最后,这些类还可把 final 类上的方法组织,因为不能将它们放在子类。这样的工具类不是原创 2020-07-20 00:50:52 · 1595 阅读 · 0 评论 -
架构师教你kill祖传石山代码重复/大量ifelse
本文就教你如何优雅消除重复代码并改变你对业务代码没技术含量的观念。1 crud 工程师的“痛”很多 crud 工程师抱怨业务开发没有技术含量,什么设计模式、高并发、OOP都用不到,就是堆CRUD。每次面试被问到“讲讲常用设计模式?”,都只能把单例讲到精通,其他设计模式即使听过也只会简单说说,因为根本没实际用过。对于反射、注解,也只是知道在框架中用的很多,但自己又不写框架,更不知道该如何使用。设计模式、OOP是世界级软件大师在大型项目的经验所得,是被证实利于维护大型项目的。反射、注解、泛型等高级特原创 2020-10-25 22:31:48 · 1441 阅读 · 0 评论 -
Joshua Bloch使用的“失败原子性”是什么?它对不可变对象有何好处?
Bloch的“失败原子性”意味着,如果方法抛出异常,则该对象之后仍应可用。通常,对象应与调用该方法之前处于相同状态。对于不可变对象,可以简单地从它是不可变的事实中获得收益。没有可以更改对象状态的操作。对象的所有方法都可以创建从原始对象派生的新对象。例如,String具有substring(int)方法。它不会更改原始字符串中的任何内容-它会创建一个新对象,其内容是所需原始字符串部分的副本。如果抛出异常,那么您将不会获得新对象-但原始String从未更改。 substring()中没有修改原始String原创 2020-10-22 09:29:32 · 1271 阅读 · 0 评论 -
面向对象编程 V.S 函数式编程
面对不断增加的需求假设有一组学生:若按姓名找出其中一个,你的代码可能如下:突然紧急需求来了,按学号找人,代码如下:又一个新需求来了,这次按照ID 找人,代码可以如法炮制:你发现,它们除查询条件不同,其余基本一模一样,别忘了代码结构重复也是代码重复!如何消除重复呢?引入查询条件,这里只需要返回一个bool值,可这样定义:通过查询条件,改造查询方法,把条件作为参数传入:于是,按名字查找变成:已经很好了,但你发现,每有一个新查询,都要做一层封装。如何才能省去这层封装?可原创 2021-10-07 15:56:45 · 735 阅读 · 1 评论 -
如何规范你的Git commit?
简介:commit message应该如何写才更清晰明了?团队开发中有没有遇到过让人头疼的git commit?本文分享在git commit规范建设上的实践,规定了commit message的格式,并通过webhook在提交时进行监控,避免不规范的代码提交。背景Git每次提交代码都需要写commit message,否则就不允许提交。一般来说,commit message应该清晰明了,说明本次提交的目的,具体做了什么操作……但是在日常开发中,大家的commit message千奇..转载 2020-08-25 02:53:15 · 1759 阅读 · 0 评论 -
IT文档中总出现的"hooks" 是什么? "钩子" ? 回调 ?
引用知乎上著名的示意图简单理解就像一些外来的钩子,在源代码之间钩取一些信息,当捕捉到感兴趣的事时,就拦截下来,让自己的代码执行一下,处理一下这个信息,然后再放出去继续之前的进程。这样就可以在不用改变源代码的情况下,做一些别的事情,比方说监控、分析和一些恶意的事专业理解在计算机编程中,术语“钩子”涵盖了一系列技术,这些技术通过截获在软件组件之间传递的函数调用或消息或事件来更改或增强操...原创 2020-03-05 16:48:25 · 2871 阅读 · 1 评论 -
Java架构师教你写代码(一) - 使用静态工厂方法(简单工厂)替代构造器
客户端获得一个类实例的传统方式是调用由类提供的public构造器。但还有一种技术,一个类可以提供public的静态工厂方法,只是一个返回类实例的静态方法。静态工厂方法与设计模式的工厂方法模式不同。在设计模式中并无直接等价的说法。2 优点2.1 实名制如果构造器的参数本身并不能描述清楚返回的对象,那么具有确切名称的静态工厂则代码可读性更佳!例如 BigInteger 类的构造器 BigInteger(int, int, Random) 返回值多半是质数,那么最好使用静态工厂方法: BigInte原创 2020-07-10 02:57:41 · 3377 阅读 · 2 评论 -
IDEA告警:Can be replaced with ‘.values().stream()‘
背景IDEA 又搞黄色了!详解可替换为.values().stream()。检查信息:通知可以简化的流API调用链。它可以避免遍历集合时创建多余的临时对象。此检查替换了以下调用链:collection.stream().forEach() → collection.forEach()collection.stream().collect(toList/toSet/toCollection()) → new CollectionType<>(collection)collec原创 2020-10-27 20:47:32 · 4014 阅读 · 0 评论 -
如何消除代码屎山中的一大坨参数列表?
每个程序员一想到,一个方法坐拥几十上百个参数,内心就不再平静了。方法为何要有参数?不同函数间需共享信息,于是有了参数传递。函数间共享信息的方式不止一种,除了参数列表,还有全局变量。但全局变量总能带来意外惊喜,所以,取消全局变量也是各大语言的趋势。但函数之间还是要传递信息的,不能用全局变量,那参数就成了最佳选择,于是,只要你想到有什么信息要传给一个函数,就会直接它加到参数列表中,参数列表也越来越长。长参数列表能有什么问题呢?还是那句现实的话,人脑能够掌握的内容有限,一旦参数列表变得很长,就很难掌控原创 2021-09-24 12:03:34 · 2379 阅读 · 4 评论 -
IDEA 告警:Stream API call chain can be simplified
通知流 API 调用链,可以简化。它允许在遍历集合时避免创建冗余的临时对象。此检查替换了以下调用链:collection.stream().forEach() → collection.forEach()collection.stream().collect(toList/toSet/toCollection()) → new CollectionType<>(collection)collection.stream().toArray() → collection.toArray()原创 2020-10-25 23:00:12 · 1437 阅读 · 0 评论