设计模式学习:概述

首先,别把程序设计不当设计!

程序的框架就是建筑物的骨架,内部实现不过是装修改造。只要骨架设计没有问题,装修起来也是得心应手。一个糟糕的程序框架,对于接下来的Debug和程序的更新换代来讲,是灾难性的(我在本学期的数字电路实验课和上学期的程序设计实验课中都深有体会…)。

一个优秀的程序,不仅体现在实际功能上和性能上的优秀,更要体现在代码复用性、可扩展性等方面。实现同样的功能,能用两百行实现为什么要写2000行?修改2份文件就能完成更新,为什么要修改十几份?这些,都是在程序框架设计的过程中要考虑的。

GOF将设计模式的宝贵经验总结成了一本经典之作:《设计模式》,为广大程序设计者提供了指导。然而,这本书实在是太太太太太太难读了,因此,在艰难地啃完整本《设计模式》之后,我打算用自己的语言,结合自己的一些理解,重新对书中的23中设计模式用简单易懂的语言进行解读。如有不当之处,烦请指正。

首先,在开始了解设计模式本身之前,我们需要了解:我们为什么需要设计模式?

设计模式的价值

设计模式并不在乎程序本身要实现的功能和它的性能如何,它试图解决的是:当用户需求发生变化时,能做最少的修改来达成这一目标。这一过程复用性和扩展性两大方面。

复用性

下面这段代码可不叫复用:

void sortInt(int a[], int len)
{for(int i=0; i<len-1; ++i)for(int j=i+1; j<len; ++j){if(a[i] < a[j])swap(a[i], a[j]);}
}void sortDouble(double a[], int len)
{for(int i=0; i<len-1; ++i)for(int j=i+1; j<len; ++j){if(a[i] < a[j])swap(a[i], a[j]);}
}

这是用冒泡排序分别对INT类型和DOUBLE类型进行排序,可见,这两段函数的函数体内容是完全一致的,有人或许认为:写好其中一个函数,直接复制粘贴到另一个函数中,不也没写多少代码吗?

这叫代码复用吗?显然不叫。我们所说的代码复用,简单来讲,是体现在二进制层面的。比如,我们调用库函数printf,printf函数作为共享库函数,在使用时可以直接链接现成的DLL文件。而如果你试图把printf的源代码直接拷贝到自己的文件中,内存中就会多出一部分内容用于存放你拷贝的这段代码,即使printf本身已经存在与内存中,这样,就造成了二进制层面上的代码浪费。

扩展性

在软件开发的过程中,必须要遵循一条规则:尽量使用扩展,而非修改原本代码的方式,对现有软件进行更新

比如,一款游戏要进行更新,你不需要整个把游戏下载一遍,只需要下载一个大小远小于游戏本身的更新包。因为可扩展性良好,开发者只需要修改或添加若干文件就可以完成游戏内容的更新,而大部分文件在更新中不需要发生变化。

这也是设计模式最想要解决的问题,比起代码复用性,这也是一个更加复杂的问题,你将在对设计模式的学习中,进一步加深对它的理解。

这里先列一些涉及到良好可扩展性的关键词:

晚绑定,运行时(runtime)多态,编译时(compile)多态,松耦合,封装…

面向对象的设计理念将会成为解决这些问题的强大武器。

八大设计原则

23个设计模式说到底,只是一种经验的理论化表述。这些设计模式,往往有许多相似之处,但万变不离其宗,所有的解决方案,都围绕下面这八大设计原则展开:

这里只提一嘴,之后对设计模式的详细学习将会加深你对它们的理解。

  1. 依赖倒置原则(DIP)

    高层模块(稳定)不应当依赖于低层模块,而二者都应当依赖于抽象(稳定)。

    抽象(稳定)不应当依赖于实现细节(变化),实现应当依赖于抽象(稳定)。

  2. 开放封闭原则(OCP)

    对扩展开放,对更改封闭。

    类模块应当是可扩展的,但是不可修改。

  3. 单一职责原则(SRP)

    一个类应该仅有一个引起它变化的原因。

    变化的方向隐含着类的责任。

  4. Liskov替换原则(LSP)

    子类必须能够替换它们的基类(IS-A“是一个”原则)

    继承应当表达的是类型抽象

  5. 接口隔离原则(ISP)

    不应该强迫客户程序依赖它们不用的方法。

    接口应当小而完备。

  6. 对象组合优于类继承

  7. 封装变化点

    设计者在变化来临时,可以在变化点一侧进行修改,而不会对另一侧产生不良影响。

  8. 面向接口编程

    统一化的接口实现了更好的封装性,极大地提高了代码可扩展性和可复用性。

    类比:秦统一度量衡,从而使得国家管理更加简便;为什么各国要争着抢着研发新技术?等人家搞好了嫖过来不好吗?答:新技术的开发者拥有指定行业标准(即统一接口)的权力,这一权力的重要性是难以言述的。

如何应用设计模式?

设计模式的应用不是说,拿到一个项目,一拍脑袋就能决定用什么设计模式。应当在对用户需求的分析后,通过对已有代码的重构来迭代地进行

同时,各个设计模式有时大同小异,相辅相成,甚至相互渗入。在解决一个问题时,我们应当以上面提到的八大设计原则为基准来判断设计的好坏,而非死板地套用模式。事实上,无脑套模式也只会增加自己编写的负担。

一个应用的稳定点和变化点将会是重点分析的内容,所谓稳定,如果程序的某些部分1个月就要发生一次变化,而有些部分1年才发生一次变化,那么后者就是稳定点。也就是说,稳定时相对的。固定一个稳定点,针对可能来临的变化搭建程序,使得程序能够做出良好的反应,这正是设计模式要做到的工作。

23个设计模式持续更新中…

1. 组件协作类

设计模式:Template Method(模板方法)
设计模式:Strategy(策略模式)
设计模式:Observer(观察者模式)
2. 单一职责类
设计模式:Decorator(装饰模式)
设计模式:Bridge(桥接模式)
3. 对象创建类
设计模式:Factory Method(工厂方法)
设计模式:Abstract Factory(抽象工厂)
设计模式:Prototype(原型机)
4. 对象性能类
设计模式:Singleton(单例类)
5. 数据结构类
设计模式:Composite(组合模式)
设计模式:Iterator(迭代器)

​ 2021.1.19


设计模式学习,23种设计模式详解:概述相关推荐

  1. 5分钟学习23种设计模式

    文章目录 5分钟学习23种设计模式 阿里巴巴开发手册 七大设计原则 设计模式类型 1.单例模式 2.简单工厂模式 3.工厂模式 4.抽象工厂模式 5.装饰器模式 6.适配器模式 7.观察者模式 8.外 ...

  2. 110.【十万字带你深入学习23种设计模式】

    Java 23种设计模式 (一).设计模式相关内容介绍 1.软件设计模式概述 (1).软件设计模式的产生背景 (2).软件设计模式的概念 (3).学习设计模式的重要性 (4).设计模式分类 2.UML ...

  3. Java设计模式:23种设计模式全面解析,墙都不扶就服你

    命令模式:将命令请求封装为一个对象,使得可以用不同的请求来进行参数化. 迭代器模式:一种遍历访问聚合对象中各个元素的方法,不暴露该对象的内部结构. 观察者模式:对象间的一对多的依赖关系. 仲裁者模式: ...

  4. 一文总结三大设计模式(23种设计模式)

    昨天我们介绍了设计模式的七大原则,今天我们介绍一下设计模式中的三大分类具体23种设计模式. 总述 三大设计模式 三大设计模式分别是:创建型.结构型.行为型三种 创建型模式主要用于描述如何创建对象(5种 ...

  5. 快速学习23种设计模式思想Design Patterns

    1.factory(工厂)追MM少不了请吃饭了,麦当劳的鸡翅和肯德基的鸡翅都是MM爱吃的东西,虽然口味有所不同,但不管你带MM去麦当劳或肯德 基,只管向服务员说"来四个鸡翅"就行了 ...

  6. 工厂设计模式(三种)详解

    什么是工厂设计模式? 工厂设计模式,顾名思义,就是用来生产对象的,在java中,万物皆对象,这些对象都需要创建,如果创建的时候直接new该对象,就会对该对象耦合严重,假如我们要更换对象,所有new对象 ...

  7. Unity学习 — 23种设计模式

    创建型模式工厂方法(Factory Method) 在工厂方法模式中,工厂方法用来创建客户所需要的产品,同时还向客户隐藏了哪种具体产品类将被实例化这一细节.工厂方法模式的核心是一个抽象工厂类,各种具体 ...

  8. 追MM与设计模式(23种设计模式巧妙解析,趣味理解)--微信公众号(程序员共读)

    创建型模式 1.FACTORY-追MM少不了请吃饭了,麦当劳的鸡翅和肯德基的鸡翅都是MM爱吃的东西,虽然口味有所不同,但不管你带MM去麦当劳或肯德基,只管向服务员说"来四个鸡翅"就 ...

  9. 【JAVA长虹键法】第一式 初识设计模式(23种设计模式)

  10. 【设计模式】23种设计模式之模板方法模式

    模板方法模式 定义 在一个抽象基类的方法中定义一个算法的骨架,算法的每一个步骤都可以延迟到子类,由子类重写.模板方法使得子类可以在不改变算法结构的情况下,重新定义算法中的某些步骤. UML类图 使用场 ...

最新文章

  1. 蜗杆单轨滑轨的驱动的统一接口
  2. 自动档车正确起步方法,自动挡开车起步7个步骤
  3. 【OpenCV3】RGB图像向CMYK颜色空间转换
  4. OpenCV测量视频编码和解码的性能(附完整代码)
  5. 【机器学习】降维技术-PCA
  6. Sentinel实现黑白名单控制详细教程来了
  7. 计算机学院创新实验室,ACM创新实验室概况
  8. 树莓派apt-get update速度慢的解决方法
  9. shell交互式输入
  10. 老年人手里有多少积蓄,该不该告诉子女?
  11. 【温故而知新-Javascript】图片效果(图像震动效果、闪烁效果、自动切换图像)...
  12. java 打文件传输超时_java I/O 一次批量插入保存文件,导致超时问题?
  13. shell脚本实例(随堂笔记)
  14. Fusion Studio 17 for Mac(视频后期特效合成软件)
  15. 超能竞速大开眼界,iQOO 5系列正式发布
  16. C语言常见例题源代码
  17. GD32F303修改外部25M晶振
  18. Kafka运维大全来了!优化、监控、故障处理……
  19. 中国医科大学2021年12月《医学遗传学》作业考核试题
  20. 无人机巡检技术要点解读,无人机巡检方案实现

热门文章

  1. 2018ccpc吉林 C:JUSTICE
  2. win10 python3.8.10下ipython无响应处理
  3. 使用element UI导航菜单默认展开选中子菜单
  4. HWND CDC HDC的转换
  5. 【Copula】考虑风光联合出力和相关性的Copula场景生成(Matlab代码实现)
  6. 最新2015浦东新区初中排名 分为四个档次
  7. 博客推荐系列第一篇:我收藏的BLOG分类
  8. 概率习题,甲乙两人一起去游“2011西安世园会”
  9. 不积跬步无以至千里,不积小流无以成江海----SAX读取xml
  10. 随手记高管专访之CEO谷风专访——随手记理财安全吗