趣学设计模式
文章平均质量分 92
设计模式:程序员的基本功,你离及格还差多少?
我爱娃哈哈
公众号:服务端技术精选
展开
-
观察者模式:如何发送消息变化的通知?
这和现实中我们打开收音机收听电台很类似。原创 2024-09-14 23:32:38 · 1121 阅读 · 0 评论 -
状态模式:如何通过有限状态机监控功能的“状态变化”?
比如,给购买的物品定义几个包裹运送状态,已下单、运送中、已签收等,当“已下单”状态变为“运送中”状态时,物流货车会把包装好的包裹运送到指定地址,也就是说,当包裹的状态发生改变时,就会触发相应的外部操作。我们先来看看状态模式的标准 UML 图:从这个 UML 图中,我们能看出状态模式包含的关键角色有三个。原创 2024-09-01 22:43:28 · 989 阅读 · 0 评论 -
策略模式:如何解决不同活动策略的营销推荐场景?
策略模式在实际的开发中很常用,最常见的应用场景是。除此之外,它还能结合工厂模式给客户端提供非常灵活的使用体验。下面,我们一起来看看吧!原创 2024-09-01 22:42:41 · 860 阅读 · 0 评论 -
模板方法模式:如何实现同一模板框架下的算法扩展?
比如,在使用 Jenkins 的持续集成发布系统中,可以定制一个固定的 Jenkins Job 任务,将打包、发布、部署的流程作为一个通用的流程。对于不同的系统来说,只需要根据自身的需求增加步骤或删除步骤,就能轻松定制自己的持续发布流程。原创 2024-08-30 22:46:36 · 1280 阅读 · 0 评论 -
访问者模式:如何实现对象级别的矩阵结构?
今天我们先来看一个原理看似很简单,但是理解起来有一定难度,使用场景相对较少的行为型模式:访问者模式。访问者模式的原始定义是:允许在运行时将一个或多个操作应用于一组对象,将操作与对象结构分离。这个定义会比较抽象,但是我们依然能看出两个关键点:一个是运行时使用一组对象的一个或多个操作,比如,对不同类型的文件(.pdf、.xml、.properties)进行扫描;另一个是分离对象的操作和对象本身的结构,比如,扫描多个文件夹下的多个文件,对于文件来说,扫描是额外的业务操作,如果在每个文件对象上都加一个扫描操作,太过原创 2024-08-30 22:45:51 · 1114 阅读 · 0 评论 -
代理模式:如何控制和管理对象的访问?
代理模式的原理非常简单,它和装饰模式很类似,都是在不改变同一个接口功能的前提下,对原有接口功能做扩展。但是,因为代理模式并不执着于链式结构,而是采用更为灵活的单一结构,在很多框架和组件的设计里都能看到代理模式的身影,比如,JDK 的动态代理机制、Spring 的 AOP 机制、Dubbo 框架等。那么,为什么代理模式能够获得如此广泛的应用呢?下面我们一起来看看。原创 2024-08-29 23:07:06 · 1536 阅读 · 0 评论 -
享元模式:如何通过共享对象减少内存加载消耗?
享元模式的原理和实现都很简单,但是应用场景却相对狭窄,它和现在我们所熟知的缓存模式、池化模式有所联系,却又有不同。看完这篇文章后,相信你会找到这个不同之处。原创 2024-08-29 23:06:04 · 601 阅读 · 0 评论 -
如何实现 API 网关的高可用性?
实际上,这一视图对于绝大多数用户来说已经足够了。比如,点击添加商品到购物车、结算、支付、等待收货……虽然对于电商系统本身来说需要考虑各种各样的情况,但是对于用户来说,购物网站这个门面就已经足够他们使用了。这也是为什么手机上的 App 虽然只有一个,但是实际上这个 App 背后需要的可能是成百上千的“一个人”在运营和研发这个 App。所以说,门面模式本身并不是一个代码实现的模式,而是组合更多的其他模式来使用的一种通用解决方案。原创 2024-08-28 23:38:10 · 1037 阅读 · 0 评论 -
如何在基础组件上扩展新功能?
在前面几篇中,我们已经了解了结构型模式中的适配器模式、桥接模式和组合模式。本篇我们要介绍的装饰模式看上去和适配器模式、桥接模式很相似,都是使用组合方式来扩展原有类的,但其实本质上却相差甚远呢。简单来说,。那么装饰模式到底有哪些需要我们重点学习的地方呢?下面,我们一起来看看吧。原创 2024-08-28 23:37:20 · 915 阅读 · 0 评论 -
组合模式:如何用树形结构处理对象之间的复杂关系?
组合模式在实现树形结构时,能够非常清楚地定义层次,并且能让使用者忽略层次的差异,以方便对整个层次结构进行控制。原创 2024-08-27 23:12:23 · 715 阅读 · 0 评论 -
桥接模式:如何实现抽象协议与不同实现的绑定?
桥接模式的原理非常简单,但是使用起来会有一定的难度,所以相对于适配器模式来说,在理解桥接模式时,。原创 2024-08-27 23:11:51 · 1135 阅读 · 0 评论 -
适配器模式:如何处理不同 API 接口的兼容性?
如果说的关注重点在于一个对象内部结构的话(常常是接口与实现的组合),那么的关注重点就在于。和。今天我们主要来聊聊最常用到的。原创 2024-08-26 23:25:50 · 1238 阅读 · 0 评论 -
原型模式:什么场景下需要用到对象拷贝?
原型模式最早出现于 1963 年的一个叫 Sketchpad 的系统中,说起 Sketchpad 你可能并不熟悉,但是说起 CAD(计算机辅助设计),现在在工程设计领域几乎无人不知,其实 Sketchpad 就被认为是现代 CAD 程序的鼻祖,主要思想是。这便是。不过在面向对象编程中,对象的原型在变化时通常不会影响新实例对象。实际上,原型模式不仅在 Java、C++ 等主要基于类的编程语言中有广泛应用,而且还在一开始就是基于原型的 JavaScript 等编程语言中得到了发扬光大。原创 2024-08-26 23:25:15 · 946 阅读 · 0 评论 -
工厂方法模式:如何解决生成对象时的不确定性?
今天我们接着来看另外一个工厂模式:工厂方法模式**(Factory Method Pattern)**。工厂方法模式就是我们俗称的工厂模式,和抽象工厂模式很类似,但。原创 2024-08-25 23:33:39 · 617 阅读 · 0 评论 -
抽象工厂模式:如何统一不同代码风格下的代码级别?
在 GoF 的《设计模式》一书中,工厂模式被分为了三种:简单工厂、工厂方法和抽象工厂。(不过,在书中作者将简单工厂模式看作是工厂方法模式的一种特例。)在实际工作中,用得比较多的就是工厂方法模式和抽象工厂模式这两类。本篇文章,我们就先看一下抽象工场模式。学习抽象工厂模式真正的重点和难点在于:如何找到正确的抽象。虽然抽象工厂模式很容易实现,但更重要的是我们要能意识到“正确的抽象往往都很简单也很底层”,比如,数据库的增删改查操作,日志的 debug、info、warn、error 级别,JVM 内存模型,等等。原创 2024-08-25 23:33:06 · 837 阅读 · 0 评论 -
建造者模式:如何创建不同形式的复杂对象?
事实上,建造者模式的代码实现非常简单,原理掌握起来也不难,而难点就在于什么时候采用它。比如,经常会遇到的以下两个问题:为什么直接使用构造函数或者使用 set 方法来创建对象不方便?为什么一定需要建造者模式来创建?原创 2024-08-24 23:36:48 · 934 阅读 · 0 评论 -
单例模式:如何有效进行程序初始化?
关于设计模式,大家可能会说:学习了很多设计模式的课程和文章,依然不会用设计模式;设计模式适用场景没有设计原则多;设计模式入门简单,精通很难;设计模式太复杂看不懂;面试前才会看设计模式;设计模式不如面向搜索编程有用;不可否认,一方面大家都很重视设计模式的学习,另一方面却又总是被设计模式搞晕,原因就在于没有真正明白设计模式最核心的到底是什么,也就是它的底层逻辑是什么。其实,关于这个问题,《设计模式:可复用面向对象的基础》这本书中早已回答过:在设计中思考什么应该变化,并封装会发生变化的概念。原创 2024-08-24 23:36:13 · 779 阅读 · 0 评论 -
如何做好 API 接口设计?
在 API 设计中,很多人会经常犯一个错误,那就是:想方设法地创建自己的 error code,用以表达自己对不同错误的个性化理解。但实际上,在 API 设计中,这是一种错误应用惯例原则的实践。比如,当使用方在使用 HTTP API 时,获得了一个 404 错误码(在 HTTP 中是未找到资源的错误),而你恰好也定义了 404 错误码(假设代表接口数据未找到),结果必然出现冲突。原创 2024-08-23 23:17:59 · 942 阅读 · 0 评论 -
如何将复杂问题拆分成小问题?
除了狭义上程序特定的关注点外,在广义上同样可以找到很多关注点,比如,我们很容易找到的关注点就是影响我们常用的软件设计的两个思考视角,也就是架构设计视角和编码实现视角。原创 2024-08-23 23:17:15 · 657 阅读 · 0 评论 -
如何提升编程中的沟通效率?
默认值的判断标准一旦不统一,很可能导致业务更大的混乱。曾经我就遇见过这么一个的案例:数据库 YN 字段默认值通常使用 0 和 1(0 为删除,1 为正确),但是突然一天来了一个很厉害的新员工,他的惯例是 -1 和 0(0是正确,-1 为删除),但他没有告知团队他对默认值的这个理解;原创 2024-08-22 23:25:01 · 891 阅读 · 0 评论 -
如何减少代码间的相互影响?
比如,汽车油门(高级组件)调用汽车引擎(低级组件),但并不是说汽车油门就比汽车引擎更复杂、功能更完善、能力更高。再比如,软件程序都得依赖底层操作系统,而你不能说软件程序就一定比操作系统复杂。原创 2024-08-22 23:24:11 · 921 阅读 · 0 评论 -
面向对象编程框架到底长什么样?
说到面向对象编程,有一个原则几乎每个程序员都知道,那就是 SOLID 原则。关于它的资料介绍也非常丰富,实践例子也很多。但实际上你很可能把 SOLID 原则都用错了,并且还无意识地一直在滥用它。之所以这么说,一方面是因为很多时候你都将每一个原则分开使用,容易造成过度解读。比如,在使用接口隔离原则时容易只关心接口,而忽略不同实现,或者不关心接口之间的关系以及和整体系统之间的关系。另一方面是因为它总是能让你无意识地将简单的问题复杂化。比如,明明只需要写一个一次性同步数据的方法,然后写完即扔,但是突然想到 SOL原创 2024-08-22 23:23:13 · 822 阅读 · 0 评论 -
如何在代码设计中实现职责分离?
绝大多数情况下,超大的类或方法都是职责划分不清导致的代码过度耦合(当然,有的算法实现本身就很复杂,进而导致出现超长的方法,这种情况不在这次的讨论范围内)。比如,当一个类包含了太多的其他类时,可以用一个简单的原则来判断职责是否过多,那就是:能否拆分出来更多的子类?如果不能,那么这个类很可能就是高内聚的,职责比较单一;如果能,那么这个类还不够内聚,职责还有多余的。原创 2024-08-22 23:22:25 · 562 阅读 · 0 评论 -
如何让源代码成为一种逻辑线索?
维护代码是程序员非常重要的日常工作之一,那么你是否曾遇见过以下问题?接手维护项目,却发现文档缺失、代码无注释,加上维护人离职,基本只能靠猜来梳理代码逻辑。代码风格过于抽象(命名过短、魔鬼数字、重名方法等),看不懂,也不敢轻易修改。运行代码出现故障时,不打日志,不抛异常,导致定位问题需要耗费很长时间。大段的if-else代码嵌套组合,调用逻辑复杂冗长,扩展性差,重构优化费时、费力。发现没,造成这些问题的原因其实都是。可读性差的代码难以理解,这不仅会造成诸多误解和麻烦,还会导致项目交付效率变低。原创 2024-08-22 23:21:43 · 889 阅读 · 0 评论 -
如何实现“最少知识”代码?
迪米特法则(Law of Demeter,简称 LoD)是由 Ian Holland 于 1987 年提出来的,它的核心原则是:一个类只应该与它直接相关的类通信;每一个类应该知道自己需要的最少知识。换句话说,在面向对象编程中,它要求任何一个对象(O)的方法(m),只应该调用以下对象:对象(O)自身;通过方法(m)的参数传入的对象;在方法(m)内创建的对象;组成对象(O)的对象;在方法(m)的范围内,可让对象(O)访问的全局变量。原创 2024-08-22 23:21:09 · 813 阅读 · 0 评论 -
如何写出“简单”代码?
如果你见过被加密的代码,那你一定知道什么叫过度简洁的代码。这样的代码机器可读,但是对于人来说几乎不可读。在现实中,我们可能都曾写过这样的代码:没有任何注释说明,不使用任何设计模式,用最直接的数据结构和算法来实现,使用字母缩写来命名变量。然后,过一段时间后,连自己都看不懂这样的简洁代码,除非再从头到尾看一遍才能回想起含义。如果换成别人,那么可想而知其阅读难度有多大。所以说,简单代码可能会很简洁,但一定不是过度简洁。下面我们再来看“简单”是什么。原创 2024-08-22 23:18:15 · 852 阅读 · 0 评论 -
如何跳出错误抽象的误区?
在软件开发中,我们都学习过一些经典的设计原则,其中包括面向对象原则(SOLID)、简单原则(KISS)、单一原则(DRY)、最少原则(LoD)、分离原则(SoC)等。分开来看这些原则时,会觉得它们都很有道理,似乎只要照着用就能提升编程能力和代码质量,但为什么到真正编码时却会有选择困难的矛盾感觉呢?其实原因就在于,。虽然设计原则是用来指导编程实践的,但如果不限定使用范围的话,在使用时就会很容易误用或滥用而导致更多问题出现。比如,KISS 原则与 YAGNI 原则是相似的,它们都是在讲如何保持简单性;原创 2024-08-22 23:17:37 · 814 阅读 · 0 评论 -
如何高效编程?
刚学会编程时,大家可能会以为:高效编程 = 高效写代码。于是开启了疯狂写代码模式,在不停地编码与调试中,度过了一年又一年,并以此沾沾自喜。但这样坚持了很多年后,却慢慢发现自己的编程效率不仅没有提高,反而越来越慢。逐渐意识到,整体编程效率之所以无法提升,是因为一直都只是关注写代码的效率。这便带来三个问题:只关心代码是否正常运行,而对最终是否满足用户需求不在意;容易陷入代码细节而忽略整体,比如,系统设计、项目进度、与他人协作等;不太关心可测试性、可维护性,以及简洁的高质量代码该怎么写。原创 2024-08-22 23:17:03 · 462 阅读 · 0 评论 -
面向对象编程有哪些优势?
现在来回答这部分开头的问题:Java 是面向对象的编程语言,可以使用面向过程或面向对象的编程范式。原创 2024-08-22 23:16:29 · 1001 阅读 · 0 评论 -
如何用软件工程方法解决开发难题?
在了解软件工程之前,我们得先搞清楚什么是软件开发。软件开发,在狭义上的定义是指软件编程,也就是我们常说的编写和维护代码的过程。但其实,从广义上来讲,软件开发是指根据用户要求构建出软件系统或者系统中软件部分的一个产品的开发过程。换句话说,软件开发是一系列最终构建出软件产品的活动。现在,我们常用“软件开发过程”这个词来表述。软件开发过程 = 定义与分析 + 设计 + 实现 + 测试 + 交付 + 维护。不管是小到一个程序的某个模块的开发,还是大到行业级的软件项目,只要是软件开发,都离不开这个本质过程。原创 2024-08-22 23:12:01 · 822 阅读 · 0 评论 -
为什么要做代码分层架构?
比如说,View 层直接调用 Model 层的组件,当 Model 层上的组件有变化时(比如, SQL 或逻辑修改),既会影响 Controller 层组件的使用,也会影响 View 层组件的使用(可参考下面的示意图)。首先,在思考如何创建 HTTP 连接这个问题的过程中,你会发现,要想通过 HTTP 发送消息,至少得打开 HTTP 连接,建立 HTTP 会话,并使用 TCP 协议,这样才能通过网络发送数据。而实际上,有的子层问题已经被前人解决过了,比如,如何使用 HTTP 协议来进行网络数据的通信。原创 2024-08-22 23:11:14 · 984 阅读 · 0 评论 -
Unix 哲学到底给现代编程带来哪些重要启示?
比如,你想使用 Java RPC 协议,可以选择 Dubbo、gRPC 等框架,RPC 协议的本质是一样的,就是远程过程调用,但是实现的组件框架却可以不同,对于使用者来说,只要是支持 Java RPC 协议的框架就行,可随意替换,这是可替换。在随后的几十年间,它逐渐形成了自己独特的编程文化,并发展出了一套影响深远的设计哲学。不同于传统系统设计理论的自顶向下,Unix 哲学注重实效,立足于丰富的经验,所以说不算是一种正规的设计方法,更像是一门艺术技艺,但是这并不妨碍它的思想精粹在软件行业中发光、发热。原创 2024-07-24 16:55:30 · 778 阅读 · 0 评论 -
怎样才能学好 Java 设计模式?
因此,一定不要中途放弃,一定要坚持住。设计模式不是万能灵药,不是银弹,设计模式能解决的问题其实是有限的,应该始终保持一个平常的心态,正确分析设计模式可以解决和不能解决的问题。比如,在设计一个网关系统时,就想着该如何使用各种模式,即便是一个小的过滤规则模块,也在想着能不能使用责任链模式,而实际上那个需求只需要简单的白名单就能解决。简单来说,设计模式从不同项目中总结出来的通用经验,是为了帮助我们快速理解现有的系统,并从中找出共性规律,如果没有足够的经验或者思考,反而容易引入错误的设计,造成更多的麻烦。原创 2024-07-24 16:58:19 · 728 阅读 · 0 评论 -
设计模式:程序员的基本功,你离及格还差多少?
先给你讲个故事。多年前刚参加工作时,刚转正不久就被派到客户现场解决一个紧急问题,对于一个刚入职场的新人小白来说,内心其实是非常惊慌无措的。刚开始还算顺利,前辈同事们已经大致定位到了问题原因,也做了一些补救措施,貌似已经没有问题了。但不久后的一天凌晨,在同步数据的过程中,系统突然就失灵了,重启之后,问题仍然出现。此时,部分数据丢失,而且客户开始越来越没有耐心。而后,另一位架构师来一起开始排查问题。原创 2024-07-19 17:39:17 · 428 阅读 · 0 评论