面试官:你不懂六大设计原则,回去等通知吧!

一、前言

不知道大家是否有这样的体会,就是在学习设计模式的时候,看了很多书籍,也照着很多示例把每个模式挨个敲了几遍,但过了一段时间后,就会忘了一大半。或者有的朋友尝试在业务编码中使用,却越用越复杂,本来一个类几个方法能搞定的业务,套用模式后会多出好多接口和类,所以用着用着就放弃了。我说的比较直接点,很多教材或博客中使用Animal、Fruit、Car这些例子来教设计模式,初衷是好的,但真没多大用,甚至会误人子弟。

最近笔者再次学习了设计模式(不知道是这些年的第多少次了),突然有了些感悟。我尽量用最简单通俗的语言描述出我想表达的,有的观点可能比较偏激或不太适合所有人,但如果大家能从这篇文章中GET到一两个点,那也值了,哈哈。

    下面我先以我个人的想法简单粗暴地理解一下设计模式的六大原则。Show Time!

二、六大原则

2.1、单一职责原则

  • 官方解释:单一职责原则(SRP:Single responsibility principle)又称单一功能原则,面向对象五个基本原则(SOLID)之一。它规定一个类应该只有一个发生变化的原因。

  • 大白话:一个类只有一个发生变化的原因,我只能说在业务编码中不太可能,或很维做到。其实大家不必纠结于有几个让类发生变化的原因。个人建议你想实践单一职责原则,最好先养成良好的编码规范,如果你平时写代码,一个类里不管什么业务方法都往里塞,一个方法里嵌套着各种判断,再好的原则也帮不也你。

  • 实践:和类名不相关的业务不要放在这个类里,和方法名不相关的代码请拆成单独的子方法。还有当你在定义一个接口、类或方法的时候,从业务的角度用心地多想一下:这段代码放这里真的合适吗?

2.2、里氏替换原则

  • 官方解释:里氏替换原则(Liskov Substitution Principle LSP)面向对象设计的基本原则之一。里氏替换原则中说,任何基类可以出现的地方,子类一定可以出现。LSP是继承复用的基石,只有当衍生类可以替换掉基类,软件单位的功能不受到影响时,基类才能真正被复用,而衍生类也能够在基类的基础上增加新的行为。

  • 大白话:这个原则其实还是很好理解的,主要是约束子类的行为,要求其行为和基类保持一致,如果替换为子类后,程序运行不正常,则说明子类没有按基类的预期实现业务,或者说子类不适合继承这个基类,对不起,请找适合的基类继承。

  • 实践:如果子类从一个基类继承后,实现基类定义的虚方法时感觉很别扭痛苦的时候,请考虑一下是否一定要从这个基类继承。

2.3、依赖倒置原则

  • 官方解释:依赖倒置原则(Dependence Inversion Principle)是程序要依赖于抽象接口,不要依赖于具体实现。简单的说就是要求对抽象进行编程,不要对实现进行编程,这样就降低了客户与实现模块间的耦合。

  • 大白话:多用接口和抽象类,少用实现类(工具类除外)。大家看框架源码的时候应该能感觉到,大神在实现框架的时候到处都是接口或抽象类,而自己的代码却是一大片的实现类,其实直接用实现类是没有问题的。架构方法中有一句叫可扩展性,其实接口和抽象类就是实现可扩展性的基石。当需要扩展原有逻辑的时候,别人用接口和抽象类的直接加个新子类继承下,你用实现类的到处一大片一大片的改,请回答我,有没有?

  • 实践:写代码的时候多考虑扩展性,如果这段代码以后扩展或变化的可能性很高,请用接口或抽象类封装下,抽象出不变的接口,将变化的部分留给不同的实现类。

2.4、接口隔离原则

  • 官方解释:接口隔离原则(Interface Segregation Principle,)使用多个专门的接口比使用单一的总接口要好。一个类对另外一个类的依赖性应当是建立在最小的接口上的。

  • 大白话:这个原则和单一职责原则有点象,好吧,其实很难区分的。主要区分点在“职责”和“隔离”两个词上。职责要求按类的功能单一性定义接口、类、方法。隔离要求最细化的定义接口,尽量避免大而全的接口,不然接口一改,所以的实现类一片报红,请回答我,有没有?

  • 实践:情愿让类实现多个单一接口,也不要实现一个大而全的接口。

2.5、迪米特原则

  • 官方解释:迪米特法则(Law of Demeter)又叫作最少知识原则(Least Knowledge Principle 简写LKP),一个类对于其他类知道的越少越好,就是说一个对象应当对其他对象有尽可能少的了解,只和朋友通信,不和陌生人说话。 

  • 大白话:电视剧经常有这个台词:“你知道的太多了”,然后一枪被崩了。这个原则也是这个道理,就是一个类尽量减少和其他类组合,这样能减少类之间的耦合,如果实现要关联,可以通过第三者(朋友)。门面模式和中介者模式就是这个原则的体现。

  • 实践:一个类里,尽量减少与太多的类接触,如果不可避免,可以用一个中介类代替。

2.6、开闭原则

  • 官方解释:在面向对象编程领域中,开闭原则规定“软件中的对象(类,模块,函数等等)应该对于扩展是开放的,但是对于修改是封闭的”,这意味着一个实体是允许在不改变它的源代码的前提下变更它的行为。该特性在产品化的环境中是特别有价值的,在这种环境中,改变源代码需要代码审查,单元测试以及诸如此类的用以确保产品使用质量的过程。遵循这种原则的代码在扩展时并不发生改变,因此无需上述的过程。

  • 大白话:其实这个原则实操性不强。如果这个原则是思想的话,上面的五个原则就是这个思想的实践,如果我们代码真的能做到职责单一、面向抽象编程且清爽的编码规范,则会很容易实现开闭原则。但现实情况是,我们的代码模块与模块,类与类高度耦合、很难见到接口或抽象类、甚至全是面向过程编码。所以在实际业务中,我们改一点代码,都要涉及很多项目、类、方法。改完很自信地说:我改动不大,不会影响线上业务的,不用测试,直接上线。请回答我,有没有?

  • 实践:尽量避免修改原有的代码(一点不改也不太可能),前期编码的时候留好扩展点,使用继承增加新子类的方式修改原有业务。

三、总结

  • 在学习设计原则和模式的时候,请先保证自己写出的代码是整洁且符合规范的,不然再好的原则和模式也拯救不了你那一大坨一大坨的类和方法,最起码的读你写的某一个方法的时候,不用拖滚动条。

  • 真正的理解你所在公司的业务和需求,先在产品和文档级别上简化业务、理清编码的思路,这样更准确地找出业务的变化点和扩展点。

  • 设计模式其实就是封装变化,所以编码的时候多用心变化点,有变化了就考虑抽象出接口或抽象类。当然,在实际业务中,多是增删改查,如果一昧的到处定义接口,也会增加复杂度,这些可以自己权衡或按团队的编码规范实施。

  • 不要刻意地去背这些模式或者照着敲几遍,没用的!实际业务编码中,发现业务变化或扩展点后再去找适合的模式。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/310147.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Asp.Net Core Filter 深入浅出的那些事-AOP

一、前言在分享ASP.NET Core Filter 使用之前,先来谈谈AOP,什么是AOP 呢?AOP全称Aspect Oriented Programming意为面向切面编程,也叫做面向方法编程,是通过预编译方式和运行期动态代理的方式实现不修改源代码的情况下给程序动态统…

C++函数模板和普通函数的调用规则

C函数模板和普通函数的调用规则: 普通函数可以进行自动类型转换。 函数模板必须严格类型匹配。 C编译器优先考虑普通函数。 如果函数模板可以产生一个更好的匹配,那么选择模板。 可以通过空模板实参列表的语法限定编译器只能通过模板匹配。 代码如下&#xff…

.NET Core技术研究-通过Roslyn代码分析技术规范提升代码质量

随着团队越来越多,越来越大,需求更迭越来越快,每天提交的代码变更由原先的2位数,暴涨到3位数,每天几百次代码Check In,补丁提交,大量的代码审查消耗了大量的资源投入。如何确保提交代码的质量和…

python最大堆heapq_Python-堆的实现与heapq(最小堆库函数)

目录简介堆是一个二叉树&#xff0c;它的每个父节点的值都只会小于或大于所有孩子节点(的值)。它使用了数组来实现&#xff1a;从零开始计数&#xff0c;对于所有的 k &#xff0c;都有 heap[k] < heap[2*k1] 和 heap[k] < heap[2*k2]。 为了便于比较&#xff0c;不存在的…

深入浅出 ASP.NET Core 与 Docker 入门课程说明

点击蓝字“角落的白板报”关注我哟加个“星标★”&#xff0c;好文必达&#xff01;深入浅出 ASP.NET Core 与 Docker 入门课程说明《深入浅出 ASP.NET Core 与 Docker 》是一门新的课程&#xff0c;本课程所有的内容全部免费&#xff0c;以图文配合视频的形式呈现。课程完整视…

微软将在新西兰建设其第一个数据中心区域

昨天新西兰各IT群都被一条消息刷屏了&#xff1a;详情可见&#xff1a;https://news.microsoft.com/en-nz/2020/05/06/aotearoa-disclosure/NZ的第一个Azure region region 是云计算的一个术语&#xff0c;也就是各大云运营商机房部署的位置。目前微软、亚马逊、谷歌等比较大的…

使用 kind 快速搭建一个 Kubernetes 测试环境

使用 kind 快速搭建一个 Kubernetes 测试环境Introkind&#xff08;Kubernetes IN Docker&#xff09; 是一个基于 docker 构建 Kubernetes 集群的工具&#xff0c;非常适合用来在本地搭建基于 Kubernetes 的开发/测试环境。想写一篇 kind 的文章很久了&#xff0c;但是之前的 …

麻雀虽小,五脏俱全

入职三年&#xff0c; 除了参与公司核心产品研发外&#xff0c;另外负责了一个2C的小项目&#xff1a;调用API拿到解析结果 & 计费。❝项目最初是.NetCore 1.0-Previewsqlite部署在IIS上&#xff0c;闲来没事&#xff0c;这个项目已经被我完全重写&#xff0c;在此记录一些…

内存迟迟下不去,可能你就差一个GC.Collect

一&#xff1a;背景1. 讲故事我们有一家top级的淘品牌店铺&#xff0c;为了后续的加速计算&#xff0c;在程序启动的时候灌入她家的核心数据到内存中&#xff0c;灌入完成后内存高达100G&#xff0c;虽然云上的机器内存有256G&#xff0c;然被这么划掉一半看着还是有一点心疼的…

Mayor's posters POJ - 2528 (离散化+线段树)

题意&#xff1a; 在1~10000000这个区间中读取n个海报的区间信息&#xff0c;后面的海报会覆 盖前面的海报&#xff0c;问最后能看到几张海报.&#xff08;本题是一道bug题下面会提&#xff09; 题目&#xff1a; The citizens of Bytetown, AB, could not stand that the c…

[PAT乙级]1018 锤子剪刀布

大家应该都会玩“锤子剪刀布”的游戏&#xff1a;两人同时给出手势&#xff0c;胜负规则如图所示&#xff1a; 现给出两人的交锋记录&#xff0c;请统计双方的胜、平、负次数&#xff0c;并且给出双方分别出什么手势的胜算最大。 输入格式&#xff1a; 输入第 1 行给出正整数 …

java 开源控件_一些好用的开源控件

工作两年&#xff0c;一直都在做些编码方面的表面功夫&#xff0c;实现了很多很炫的功能&#xff0c;在此写下一些体验。有些比较小的dll文件我会发上来&#xff0c;如果是开源组织的代码我会把地址附上&#xff0c;毕竟人家是会更新的。大家还有什么好用的开源控件欢迎补充。一…

揭秘 .NET 5 和Java 互操作

早早的.NET团队就立下了.NET和Java互操作的flag&#xff0c;如果你去翻一翻dotnet/runtime库&#xff0c;丝毫看不出来仓库内在搞支持。xamarin/java.interop库一直有Mono和Java互操作的实现&#xff0c;那么100%的实现.NET和Java互操作就是它&#xff0c;这两篇文章就是和你一…

java中的asList_Java Arrays.AsList原理及用法实例

java.util.Arrays的asList方法可以方便的将数组转化为集合&#xff0c;我们平时开发在初始化ArrayList时使用的比较多&#xff0c;可以简化代码&#xff0c;但这个静态方法asList()有几个坑需要注意:一. 如果对集合使用增加或删除元素的操作将会报错如下代码&#xff1a;List l…

为什么顶尖高手,都是长期主义者?

点击蓝字关注&#xff0c;回复“职场进阶”获取职场进阶精品资料一份在当下这个浮躁的社会&#xff0c;很多人都认为“快”才是真理&#xff0c;“慢”就是原罪。大家都对一夜腾飞的故事津津乐道&#xff0c;却觉得坚守一生最终获得大成的故事不够性感。但事实是怎么样的呢&…

java中函数是什么_[一] java8 函数式编程入门 什么是函数式编程 函数接口概念 流和收集器基本概念...

本文是针对于java8引入函数式编程概念以及stream流相关的一些简单介绍什么是函数式编程?java程序员第一反应可能会理解成类的成员方法一类的东西此处并不是这个含义,更接近是数学上的函数看一下百度百科中关于函数的说明函数的定义&#xff1a;给定一个数集A&#xff0c;假设其…

分布式系统不得不说的CAP定理

21天学会C语言&#xff1f;3天学会弹钢琴&#xff1f;放弃一切错误方法&#xff0c;从今天开始“刻意练习”&#xff0c;因为这才是最强大的&#xff0c;也是唯一正确的学习方法。--《刻意练习》Anders Ericsson引言CAP问题已经成了计算机科学中一个研究领域&#xff0c;之前说…

[PAT乙级]1021 个位数统计

输入格式&#xff1a; 每个输入包含 1 个测试用例&#xff0c;即一个不超过 1000 位的正整数 N。 输出格式&#xff1a; 对 N 中每一种不同的个位数字&#xff0c;以 D:M 的格式在一行中输出该位数字 D 及其在 N 中出现的次数 M。要求按 D 的升序输出。 输入样例&#xff1a;…

Largest Rectangle in a Histogram (动态规划+奇思妙想单调栈)求最大矩状图面积

感觉动态规划都是玄妙的很&#xff0c;思维题吧&#xff08;单调栈思维&#xff09; 题解&#xff1a;让求最大矩形面积&#xff0c;宽为1&#xff0c;暴力超时 可以发现 当第i-1个比第i个高的时候 比第i-1个高的所有也一定比第i个高 于是可以用到动态规划的思想 令l…

ASP.NET Core分布式项目实战(详解oauth2授权码流程)--学习笔记

最近公司产品上线&#xff0c;通宵加班了一个月&#xff0c;一直没有更新&#xff0c;今天开始恢复&#xff0c;每日一更&#xff0c;冲冲冲任务13&#xff1a;详解oauth2授权码流程我们即将开发的产品有一个用户 API&#xff0c;一个项目服务 API&#xff0c;每个服务都需要认…