图解设计模式,看完秒懂!!!

在这个软件发展日新月异的时代,软件产品推陈出新应接不暇,软件需求更是变化莫测,难以预判。作为技术人员,我们在软件开发过程中常常会遇到代码重复的问题,这就不得不对系统进行改动、重构,所以良好稳固的软件架构就显得至关重要。设计模式正是为了解决这些问题,它针对各种场景提供了最适合的代码模块复用解决方案。

设计模式最早于1994年由Gang Of Four(四人小组)提出并以C++面向对象语言作为示例,如今大量应用于Java、C#等面向设计语言所开发的程序中。其实设计模式和编程语言是无关的,编程语言只是与计算机沟通的媒介,它们都可以用自己的方式去实现设计模式。从某种意义上讲设计模式并不是某种具体的技术,而更像是一种思想,一种格局,本书将以时下最流行的Java面向对象编程语言为例,对23种设计模式逐一拆解分析。

在学习设计模式之前我们得先搞清楚到底什么是面向对象。我们都生活在现实世界里,这里充满了各种对象,如本章封面图所示,其中的山川河流、花鸟鱼虫、高楼大厦、车水马龙,我们每天都要面对他们,与他们沟通、互动,这是对面向对象最简单的理解。为了将现实世界重现于计算机世界中,我们想了各种方法针对这些对象建立数字模型(类),但是理想很丰满而现实很残酷,我们永远也无法包罗万象这大千世界中的万事万物。而当人们在“造物”过程中发现其实类与类之间有着千丝万缕的关联,于是想到面向对象特有的编程方法,利用封装、继承、多态的方法去建模,大量的减少了重复代码、降低类间耦合,像拼积木一样组装了整个“世界”。“封装”、“继承”和“多态”就是面向对象的3大特性,这些都是设计模式的基石,我们必须要理解掌握。

1.1 封装

对于封装的概念,我们就以现实世界中的事物举例,比如胶囊对于各类药物混合的封装;钱包对于现金、身份证及银行卡的封装;电脑机箱对于主板、CPU及内存等零件的封装等等,封装可以说在我们生活中比比皆是、随处可见。我们举一个现实生活中最常见的例子,我们都用吸管喝过饮料吧,如图1-2所示。

代码清单1-2 哈士奇类Husky

如代码清单1-2所示,为了延续父类的基因,哈士奇类在第一行的类定义后用“extends”关键字声明了对父类Dog的继承关系。第3行构造时以“super”关键字调用了父类的构造方法,并初始化了狗的品种breeds为“哈士奇”,当然年龄一并会被父类初始化为0岁。我们可以看到哈士奇类的代码已经变得特别简单了,并没有定义任何getter或setter方法,也没有出现犬吠方法的定义,而当我们调用这些方法时能神奇般地得到结果,自然而然地,它沿用了父类的方法。只是单单继承父类的本领还是不够的,哈士奇类更应该有自己的特色,比如增加自己的属性、方法,可以看到代码第7行我们增加了哈士奇特有的“拉雪橇”本领,这是父类所不能及的。除此之外,哈士奇吠叫起来比较特殊,可能是基因突变或者是返祖现象导致,这时我们甚至可以重写吠叫方法让它发出狼的叫声。接下来其他的子类继承各尽其能,比如贵宾犬可以作揖,藏獒可以看家护院等等,读者可以自己发挥。总之,继承的目的并不是一成不变的全盘照搬,基于父类的基因,子类更可以灵活扩展。

扩展阅读

大家都知道任何类都有一个toString()方法,但我们根本没有声明它,这是为什么呢实这就是从Object类继承下来的优良传统,因为Object是一切类的祖先类

1.3 多态

众所周知,在我们创建对象的时候通常会再定义一个引用指向它以便后续进行对象操作,而这个引用的类型则决定着其能够指向哪些对象,用犬类定义的引用绝不能指向猫类对象,所以说对于父类定义的引用只能指向本类或者任何子类实例化出来的对象,这就是一种多态。除此之外还有其他形式的多态,例如抽象类引用指向子类对象,或者接口引用指向实现类的对象。

我们继续以上一节中的犬类继承为例,如果以犬类Dog作为父类,那么哈士奇、贵宾、藏獒、吉娃娃等等都可以作为其子类,如果我们定义犬类引用dog,那么它就可以指向犬类的对象,或者其任意子类的对象,翻译成大白话就是“哈士奇是犬类,藏獒是犬类……”。下面我们用代码来表示,请参看代码清单1-3。

代码清单1-3 犬类多态构造示例

如代码清单1-3所示,前3行都没有任何问题,犬类引用可以指向狗,也可以指向哈士奇,这让dog引用变得更加灵活、多变,可以引用任何本类或子类对象。然而第5行代码就会出现问题,让哈士奇的引用指向犬类Dog的对象就行不通了,这就好像是说“犬类就是哈士奇”一样,逻辑混乱。

再进一步讲,多态其实是利用了继承(或接口实现)这个特性体现出来的另一番光景。我们以食物举例,中华美食博大精深,菜品众多且色香味俱全,这都离不开各种各样的食材,如图1-6所示。

1.4 电脑与外设

为了更透彻深入地理解面向对象的特性,以及设计模式如何巧妙利用面向对象来组织、布局各种模块协同工作,我们以一个形象贴切的例子切入实战部分。如图1-8所示,相信很多读者都没有见过这种电脑,没错,这是一台早期的个人电脑,可以明显看到它的键盘、主机和显示器等都是集成为一体的。

电脑:“我宣布,从现在开始USB接口晋升为我的秘书,我只接收它传递过来的数据,谁要找我沟通必须通过它。”

USB接口:“要接驳我的设备是什么我不关心,但我规定你必须实现我定义的readData(Data data)这个方法,但具体怎样实现我不管,总之我会调用你的这个方法把数据读过来。”

USB键盘:“我有readData(Data data)这个方法,我已经实现好了,传过去的是用户输入的字符。”

USB鼠标:“我也一样,但传过去的是鼠标移动或点击数据。”

USB摄像头:“没错,我也实现了这个方法,只是我的数据是视频流相关的。”

USB接口:“无所谓你们是什么类型的数据,只要传过来转换成Data就行了,我接收你们的接驳请求,除了PS2鼠标。”

PS2鼠标:“@电脑,老大这怎么办找来这个USB接口太霸道了,我们根本无法沟通,你们都不能尊重一下老人吗

Computer电脑:“你自己想办法,要顺应时代潮流,与时俱进。”

PS2鼠标:“……”

显然,通过这场对话我们有了更深刻的认识,电脑中封装了一个USB接口,这就是“封装”,而键盘、鼠标及摄像头都是USB接口的实现类,广义上理解这就是一种“继承”,所以最终电脑的USB接口就能接驳各种各样的USB设备的,这就是“多态”,我们来看它们的类结构图,如图1-10所示。

另外,随机送出5本,抽奖即可,明天中午12点开奖,中奖者把收货信息及时写入,三天内发出!

声明:本站部分文章及图片源自用户投稿,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!

上一篇 2021年6月16日
下一篇 2021年6月16日

相关推荐