程序员经常说的「设计模式」到底是什么?

当程序员说去「设计模式」时,你是否会一脸懵逼,到底什么是设计模式呢?

很多人应该听说过设计模式(Design pattern),又或多或少的看过或用过设计模式,但是实际用在开发过程中总有点心有余而力不足的感觉。那肯定是对设计模式的理解有少许偏差或者不够深入。先不谈某种具体的模式,先来看看什么是设计模式?

什么是设计模式?

设计模式是一套代码设计「经验的总结」。项目中「合理的」运用设计模式可以「巧妙的解决很多问题」。

经验的总结:抱着「代码虐我千百遍,我待代码如初恋」的心态,最终得出来的「套路」。

合理的:要对设计模式的使用场景有一定的认识后才使用,「不要滥用」。如:输出一句“hello world”,非要强行给加上各种模式。

问:“为什么”,答:“总感觉少了模式!”。

 

巧妙的解决了很多问题:被广泛应用的原因。

为什么要提倡“Design Pattern呢?根本原因是为了代码复用,增加可维护性。那么怎么才能实现代码复用呢?

设计模式之六大原则

开闭原则(Open Close Principle)

1988年,勃兰特·梅耶(Bertrand Meyer)在他的著作《面向对象软件构造(Object Oriented Software Construction)》中提出了开闭原则,它的原文是这样:“Software entities should be open for extension,but closed for modification”。

  • 意思:软件模块应该对扩展开放,对修改关闭。
  • 举例:在程序需要进行新增功能的时候,不能去修改原有的代码,而是新增代码,实现一个热插拔的效果(热插拔:灵活的去除或添加功能,不影响到原有的功能)。
  • 目的:为了使程序的扩展性好,易于维护和升级。

里氏代换原则(Liskov Substitution Principle)

  • 意思:里氏代换原则是继承复用的基石,只有当衍生类可以替换掉基类,软件单位的功能不受到影响时,基类才能真正被复用,而衍生类也能够在基类的基础上增加新的行为。
  • 举例:球类,原本是一种体育用品,它的衍生类有篮球、足球、排球、羽毛球等等,如果衍生类替换了基类的原本方法,如把体育用品改成了食用品(那么软件单位的功能受到影响),就不符合里氏代换原则。
  • 目的:对实现抽象化的具体步骤的规范。

依赖倒转原则(Dependence Inversion Principle)

  • 意思:针对接口编程,而不是针对实现编程。
  • 举例:以计算机系统为例,无论主板、CPU、内存、硬件都是在针对接口设计的,如果针对实现来设计,内存就要对应到针对某个品牌的主板,那么会出现换内存需要把主板也换掉的尴尬。
  • 目的:降低模块间的耦合。

接口隔离原则(Interface Segregation Principle)

  • 使用多个隔离的接口,比使用单个接口要好。
  • 举例:比如:登录,注册时属于用户模块的两个接口,比写成一个接口好。
  • 目的:提高程序设计灵活性。

迪米特法则(最少知道原则)(Demeter Principle)

1987年秋天由美国Northeastern University的Ian Holland提出,被UML的创始者之一[Booch]等普及。后来,因为在经典著作《 The Pragmatic Programmer》而广为人知。

  • 意思:一个实体应当尽量少的与其他实体之间发生相互作用,使得系统功能模块相对独立。
  • 举例:一个类公开的public属性或方法越多,修改时涉及的面也就越大,变更引起的风险扩散也就越大。
  • 目的:降低类之间的耦合,减少对其他类的依赖。

单一职责原则( Single responsibility principle )

该原则由罗伯特·C·马丁(Robert C. Martin)于《敏捷软件开发:原则、模式和实践》一书中给出的。马丁表示此原则是基于汤姆·狄马克(Tom DeMarco)和Meilir Page-Jones的著作中的内聚性原则发展出的。

  • 意思:一个类只负责一个功能领域中的相应职责,或者可以定义为:就一个类而言,应该只有一个引起它变化的原因。
  • 举例:该原则意思简单到不需要举例!
  • 目的:类的复杂性降低,可读性提高,可维护性提高。

刚入行的时候,在想什么样的代码是好代码?看到很多前辈的文字都说好的代码要符合「高内聚,低耦合」,但是我听到这样的解释,是这样的

而现在对设计模式有了一定程度上的学习,感觉懂了一些,小伙伴们你们学会了吗?

高内聚,低耦合?

  • 内聚是从功能角度来度量模块内的联系,一个好的内聚模块应当恰好做一件事。它描述的是模块内的功能联系;
  • 耦合是软件结构中各模块之间相互连接的一种度量,耦合强弱取决于模块间接口的复杂程度、进入或访问一个模块的点以及通过接口的数据。

转载于:https://www.cnblogs.com/boxjs/p/9005703.html

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

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

相关文章

每日一题(11)—— 结构体大小

分析下面的代码&#xff0c;求运行结果&#xff08;64位&#xff09;。 #include <stdio.h>struct {int id;unsigned char arg;char *p;void (*func)(void); } test;int main(void) {printf("sizeof(test.id):%d\n", sizeof(test.id));printf("sizeof(tes…

缓存服务器在Linux下的运用

本文只介绍memcached缓存服务器的PHP的API&#xff0c;想查看其他关于Memcached缓存服务器的API文档案&#xff0c;请访问 http://www.danga.com/memcached/一、环境需求安装Memcached缓存服务器须要 libevent库的支持&#xff0c;所以请在安装Memcached缓存服务器之前检查有没…

Linux 内存管理之vmalloc

走进vmalloc 根据前面的系列文章&#xff0c;我们知道了buddy system是基于页框分配器&#xff0c;kmalloc是基于slab分配器&#xff0c;而且这些分配的地址都是物理内存连续的。但是随着碎片化的积累&#xff0c;连续物理内存的分配就会变得困难&#xff0c;对于那些非DMA访问…

composer不成功的原因

1在下载好composer.setup的过程中&#xff0c;出现了错误&#xff0c;安装好composer.setup后并没有在path中出现关于composer.setup/bin的目录&#xff0c;如果没有出现这个path的这个路径的话&#xff0c;那么你在cmd里面就会出现找不到这条命令的情况 2.安装好phpstudy的这个…

《观止》书评

收到《观止》一书已经一周了&#xff0c;因为工作很忙的原因&#xff0c;前几天完全没有看。到了周末才稍有点空闲&#xff0c;便拿起手边的这本《观止》一起。谁知一“观”而无法“止”。硬是活生生的占用了我整个本来打算用来补觉的周末。 严格说来《观止》并不算是技术书籍…

每日一题(12)—— .h头文件中ifndef/define/endif的作用

.h头文件中ifndef/define/endif的作用&#xff1f; 分析&#xff1a; 防止头文件被重复包含。 #ifndef _TEST_H_ #define _TEST_H_/* test.h */#endif /* _TEST_H_ */假如在a文件和b文件中都使用这个test.h&#xff0c;假如编译器先编译a&#xff0c;执行.h的内容&#xff0…

进程是如何使用内存的?

程序运行概述程序&#xff08;我们这里只讨论单进程情况&#xff0c;存在多进程的程序如淘宝微信等不展开讨论&#xff09;镜像存在磁盘中&#xff0c;运行时将镜像加载至内存RAM中&#xff0c;然后开始执行。先来看一下CPU的多级存储结构&#xff0c;CPU通用寄存器访问速度最快…

如何用SQLDMO在ASP.NET页面下实现数据库的备份与恢复

我们知道&#xff0c;用SQLDMO可以实现对数据库的备份与恢复&#xff0c;下面给出简单的实现方法。首先需要添加对SQLDMO引用1.实现数据库的备份&#xff1a;1/**//// <summary> 2 /// 数据库备份 3 /// </summary> 4 /// <returns>备份…

每日一题(13)—— #includefile.h 与 #include “file”的区别

#include<file.h> 与 #include “file”的区别&#xff1f; #include<file.h>&#xff1a;编译器从标准库路径开始搜索file.h&#xff1b; #include “file”&#xff1a; 编译器先从当前目录下搜索file.h&#xff0c;找不到&#xff0c;再到标准库路径搜索file…

TP4056 实现可编程锂电充电器+电量计

本文作者&#xff1a;t3486784401链接&#xff1a;https://www.mydigit.cn/forum.php?modviewthread&tid250916&extra手头有些容量非常小的软包锂电&#xff0c;直接使用市面上的大功率充电板&#xff08;500mA/1A&#xff09;倍率太大&#xff0c;容易损坏电池。索性…

ASP.NET获取路径的方法

HttpContext.Current.Request.PhysicalPath; // 获得当前页面的完整物理路径.比如 F:\XFU.NSQS\project\website\Default.aspxHttpContext.Current.Request.PhysicalApplicationPath; // 获得当前程序运行的物理路径比 如F:\XFU.NSQS\project\website\HttpContext.Current.S…

《我也能做CTO之.程序员职业规划》 水准之上,期望以下

高老师的新作已经大致拜读了&#xff0c;看完之后确实有点不吐不快的话。在这献丑一说&#xff0c;大家多批评指正。个人感觉老老师这书写的实在是&#xff0c;水准以上&#xff0c;期望之下。这话怎么解呢&#xff0c;简单的说&#xff0c;确实这书达到了高老师的平均水准&…

电车防盗报警器电路原来是这样的!

前几天电路菌从电车上拆开了一个防盗报警器&#xff0c;今天来看看防盗报警器这内部的电路到底是怎样的&#xff01;上图就是防盗报警器的主机&#xff0c;引出来的这根黑线是天线。在防盗报警主机的侧面&#xff0c;可以看到印刷有文字“RP-48V-64V”&#xff0c;应该是指这主…

vue 重定向

//重定向 { path: /*, component: Home} 转载于:https://www.cnblogs.com/1032473245jing/p/9018304.html

每日一题(14)—— 交换a,b的值(不使用中间变量)

如何将a,b的值进行交换&#xff0c;并且不使用任何中间变量&#xff1f; 推荐答案&#xff1a; a a ^ b; b a ^ b; a a ^ b; 下面的答案不好&#xff0c;可能会导致越界的问题 a a b; // 可能越界 b a - b; a a - b;

买到假芯片,血的教训!

关注星标公众号&#xff0c;不错过精彩内容作者 | 写代码的篮球球痴素材来源 | 云汉芯城2021年太难了&#xff0c;芯片涨价不说&#xff0c;涨价之后还买不到芯片&#xff0c;芯片交货周期已经超过一年了。嵌入式Linux1涨价、缺货 ——> 翻新、假货在芯片涨价、缺货的背景下…

Windows 7 :微软目前最好的操作系统

好消息&#xff0c;各位&#xff01;如果你是 PC 用户&#xff0c;如果你仍然在使用有 8 年历史的 Windows XP&#xff0c;或者令人讨厌的 Windows Vista &#xff0c;现在你终于可以解脱了&#xff1a;Windows 7 就在眼前。微软交付了一套设计巧妙、改进巨大的操作系统&#x…

[Robot Framework] 怎么做数学运算?

运用BuiltIn里面的Set Variable 转载于:https://www.cnblogs.com/MasterMonkInTemple/p/9020406.html

每日一题(15)—— static有什么用途

static有什么用途&#xff1f;&#xff08;请至少说明两种&#xff09; (1) 在函数体&#xff0c;一个被声明为静态的变量在这一函数被调用过程中维持其值不变。 (2) 在模块内&#xff08;但在函数体外&#xff09;&#xff0c;一个被声明为静态的变量可以被模块内所用函数访问…

解剖几个有点难度的C笔试题

总结了几个比较经典的笔试题目&#xff0c;这些题目是在面试中遇到的&#xff0c;有难度&#xff0c;但是不是那种特别难的&#xff0c;比较有代表性&#xff0c;如果正在找工作的话&#xff0c;可以看看&#xff0c;丰富一下自己的知识库。1.题目一求下面代码输出&#xff1a;…