设计模式初探

设计模式有多么重要?身为在校学生,很少有人能有机会参与到真正的大型项目的设计中来,相信很多人在学习了C++和Java等面向对象的语言后,能够用面向对象语言提供的语法和特性设计一些程序并进行了一些实践后,就认为自己对面向对象有了一些体会。对于很多人来说,精通面向对象编程就等同与熟悉c++/java/等等其他的语法,对语法关注的程度要远远超过语言特性本身。我发现越是特别是有经验的C程序员,在学习C++时这种表现尤为明显。

最近学习设计模式,由于是零基础,在同学的推荐下,入手了被成为设计模式圣经的Gof所著《设计模式--可复用面向对象软件的基础》。虽然之前在课程上实践中也有过一些C++的使用经历,并且也曾经用C++完成过几个课程作业的开发,但是当看到这本书时还是觉得很难啃。我觉得原因在于两点:

一是这本书太过专业。这本书着重与将23种设计模式的适用环境和具体设计方法进行严谨,统一,细致的描述,这显然过于专业了,对于我这种没有进行过大型面向对象软件开发的“小白”来说,着实有点不会走就要学飞的感觉。

第二点原因,很明显,是我太菜。虽然使用过C++做过一些系统,并且也花了一些时间学习C++的语法和编程规范,但是不得不承认我其实对面向对象编程并没有实质的感悟。在笔者利用C++开发的几个系统中,对于对象的设计简直是糟糕透顶的。当然,在实施系统编码之前我也会对系统进行分析及对象建模,但是方法十分笨拙。我所做的就是从需求描述中提取里面的名词,将他们定义为类,然后从需求描述中提取动词,将这些动词定位到对应的类并定义为他们的成员变量。这种方法虽简单,却十分糟糕。回想一年前曾经使用C++写的一个五子棋对战程序,我就是采用这种方法,对后导致的后果是在程序开发越到后面时,麻烦越大,我总是在为一开始那些不良的设计埋单,总是为了实现一些新的功能或改写旧的功能做很多的walk around,最后整个程序虽然完成,但我自己的感觉依然是一大mess!我都很难想象如果再增加新的功能,会导致多大的烦恼!由此可见,一个良好的设计,是多么的重要。

所以我认为,面向对象的精髓,应该是设计模式!

当然GoF的书固然经典,但确实不是和我这样的入门学习者。经过一段时间在豆瓣的探索,很多人推荐入门看Alan Shalloway的《设计模式解析》。入手此书后,才发现它其实也不厚:-)。几天下来抽空看了几章,给我感触很大。和Gof不同的是,这本书并没有对各个设计模式进行详细的讲解与总结,而是在花很多篇幅告诉读者:我们为什么要设计模式?为什么模式会这样设计?什么样的面向对象设计才是优质的?不得不说,此书,真乃设计模式入门神做。作者将更多的精力集中在why,而不是how,而这,正是我这个入门者最急需的知识。

设计模式的作用,就是把面向对象设计中常见的问题和相应的最优解决总结出来,以给我们的对象设计提供前车之鉴和指导。是的,这就是人们时常所说的,“站在巨人的肩膀上”;站的更高,才能看得更远!这边文章中,我想对设计模式解析一书中讲到的前两个模式Facade和Adapter模式总结下。书中将这两个模式放在模式实例的最开始进行讲述,我相信是有很大理由的--他们很简单,而且非常常用。很多人就算没有学习过设计模式,在自己系统的设计中也会或多或少使用到。

Facade

“Facade”,e文里是“表面”,“前面”的意思。这个名字确实起的很传神~。

《设计模式》一书中对Facade模式的描述是:“为子系统中的一组接口提供一个统一接口。Facade模式定义了一个更高层的接口,是子系统更加容易使用”。看,这就是GoF,其实这个模式很简单,但是他总是试图用一些通用的方法去描述,让你初看时,云里雾里。

Alan书中一个简单的例子,顿时叫人明了了--其实Facade模式对于很多人都不陌生,哪怕你没有接触过设计模式,很多人在设计系统时或多或少会使用到这种思想。比如你在开发一个网购系统,系统中有买家,卖家、产品信息以及买卖双方之间的各种交易;我们会在数据库中定义相关的表格来存储这些信息,比如用户表,产品表,交易表。系统实施时,买家、卖家、系统都可能随时操作数据空中的相关表格,他们都遵循着一个统一的操作模式:打开数据库->执行SQL语句->验证结果->关闭数据库。于是乎我们想不如创建一个DatabaseManager类,只提供给用户他们感兴趣的一个统一的,简单的接口,而屏蔽掉这些实现细节。系统运行时我们构造这么一个管理类来满足各种数据库相关操作的请求。

Facade模式带来的优点是显而易见的:

1.减少了冗余代码,我们不必每次用相似的代码去完成相似的工作

2.更好的封装性,只提供给用户他们关心的接口,而用户不用去关心实现细节

3.更好的移植性,当我们的数据库系统更改时我们不必更改任何用户代码,只需要更改数据库管理类的实现代码。这也是Alan在书中提到的队封装的理解:“封装那些可能会变化的东西”。

Facade,很简单,也很常用。

Adapter

首先还是GoF,这是他们对Adapter的定义:“Adapter将一个类的接口转化为客户希望的另一个接口,使原本由于接口不兼容而不能一起工作的类能够一起工作。”

Adapater模式的存在,就是问了解决兼容问题,是系统移植的通用解决方案。想想我们的java语言。java语言的一大特色就是跨平台,用户可以一次编写,多次执行。java源代码首先被编译成字节码,这些字节码运行在java虚拟机上,而java虚拟机可以运行在不同的操作系统之上,而实现了“跨平台”。这样看来,java虚拟机就是一个巨大的Adapter。统一的字节码,经过JVM的“翻译”,变成可以各个平台上执行的程序流。JVM就像是用户代码和实际操作系统API之间的Adapter,它的存在让用户程序不用做任何更改即可运行在不同的系统之上。

再举一个例子,我近期的项目中也涉及到系统移植的问题。需要把lwIP(一个轻量级的TCP/IP协议栈的实现)移植到一个嵌入式实时系统上去。由于lwIP在协议栈的实现中,使用了许多依赖操作系统的系统功能,如信号量,内存管理,定时器,消息队列,网卡驱动等等。lwIP的设计者为了方便移植,将所有这些系统功能抽象成一套自己的API列表,并提供他所关心的功能和函数原型,lwIP的实现中所有对这些API的引用均采用这些函数;而移植者为了把协议栈移植到自己的系统上,只需要根据自己的系统API来实现这些统一接口就好。比如线程创建函数被lwIP同意定义为sys_thread_new(若干参数),移植者只需要将这个函数根据自己的系统API进行实现即可,比如在Linux上可能是pthread_create,在win下可能是CreateThread--不管是什么,lwIP都不care,你只要提供了正确的函数就行了。当然这是例子是面向过程的应用,在面向对象中,一样如此。

这样看来,Adapter和Facade看起来好像没什么区别了。貌似都是提供一层封装的接口给用户,便于用户使用。但是他们之间还是有区别的,只是相当微妙。

Facade着重于实现细节隐藏,而Adapter着重于移植。在实现上,他们都是用已有的老接口实现新的接口提供给用户,但是不同在于这个新的接口--Facade模式中新的接口也是Facade实现者自己定义的,而Adapter的实现着就没有这么大的权力了,因为他们提供的新接口必须满足一些现有的接口形式。

这就像你去餐厅吃饭,服务生问你吃什么。你可以说“随便,好吃就行”。这时餐厅的选择就很多了,只要给你好吃的就行,而具体是什么以及怎么做的,你不care---这就是Facade;而如果你说“我要牛排”,餐厅的选择就少了,他们所作的就是给你提供牛排,而牛排是怎么做的,你不care,你只要是牛排就行了---这就是Adapter。

总结一下:这两个设计模式虽然简单常用,但是作用也是不可小视的。虽然我们在解决实际问题中很多人都自然会用到这两个模式中提供的方法去设计,但是鲜有人总结出来。设计模式的作用就是将这些最常用并且行之有效的设计方法总结出来,让你的设计更加优质。设计模式的要点不在于单个模式的理解,而在于在实际系统中多个模式组合起来,灵活应用!

Facade和Adapter相关推荐

  1. 设计模式解析(五)——几种设计模式之Facade和Adapter

    由于个人时间原因,无法详细描述这些模式,暂且记录下来以后慢慢补充详细. Facade模式 Facade模式:关键特征   意图 希望简化原有系统的使用方式.需要定义自己的接口. 问题 只需使用某个复杂 ...

  2. Facade与Adapter模式应用

    前言 作为设计模式第一篇随笔,首先以个人粗浅了解谈一谈何为设计模式. 简单来说,对于某一类新问题,可以使用前人为旧问题设计过的解决方案.将前人设计的模式应用到新问题上,不仅避免了许多可能碰壁的尝试,同 ...

  3. 14Facade(门面)模式

    技术交流QQ群:1027579432,欢迎你的加入! 1.接口隔离模式 在组件构建过程中,某些接口之间直接的依赖常常会带来很多问题.甚至根本无法实现.采用添加一层间接(稳定)接口来隔离本来互相紧密关联 ...

  4. 初涉c#设计模式-proxy pattern-从中国足球黑哨开始

    好吧,这次的设计模式,我从最爱的足球谈起. 嗯,球员不是演员,想要行贿球员好比门将放球进去,这样演起来真的挺难,但作为裁判,对于一些争议性的问题,往往可以通过一些手段让他"看清"到 ...

  5. Flyweight设计模式

    Flyweight设计模式 Today we will look into Flyweight design pattern. Table of Contents [hide] 1 Flyweight ...

  6. Java中的Flyweight设计模式

    Today we will look into Flyweight design pattern. 今天,我们将探讨Flyweight设计模式. 轻量化设计模式 (Flyweight Design P ...

  7. [大话设计模式C++版] 第17章 在NBA我需要翻译 —— 适配器模式

    源码可以在这里找到 大话设计模式C++版 篮球翻译适配器 //Player.h 球员基类 #include <QString>class Player {protected:QString ...

  8. JavaSE回顾笔记Ⅲ

    JavaSE回顾笔记Ⅲ ​ 前言,,懒得写了,去看2吧,开头有几句废话. ​ day13和上一个重复,是因为这一个是完全自学的一个章节,因为并没什么用,但是很感兴趣就简单看了一下.因为强迫症,不想向后 ...

  9. 《设计模式解析》读书笔记

    Facade模式 GoF模式中的定义: 为子系统中的一组接口提供一个统一的接口.Facade模式定义了一个更高层的接口,使子系统更容易使用. 通过Facade,我们将以一种更简单的方式来使用原有系统. ...

最新文章

  1. 【C#】登陆次数限制
  2. 跟着“路线图”,我们一起遨游机器学习的世界!
  3. struct和class内存大小的计算
  4. linux vino vnc,CentOS 远程桌面(vnc,vino)
  5. boost::geometry::detail::copy_segments的用法测试程序
  6. Mac更新VSCode写权限被拒绝 Cannot update while running on a read-only volume
  7. 机器学习-降维之主成分分析PCA算法原理及实战
  8. Linux 基础命令上
  9. sun jdk 与jdk_Sun过去的世界中的JDK 11和代理
  10. 实验4 数据查询--简单查询
  11. Spring web应用最大的败笔
  12. 队列 开源 php,消息队列 - 基于think-queue消息队列 – 基于ThinkPHP和Bootstrap的极速后台开发框架...
  13. qt5使用触屏 偶尔没响应_戴着手套玩手机!你试过吗?触屏灵敏又保暖,冬天再也不冻手~...
  14. 20181031-1
  15. 配置OpenLDAP使用TLS通信
  16. 通用验证码识别SDK免费开源
  17. java获取pdf文件首页图片,用来当做封面
  18. 线性代数---魏福义版 第一章习题答案
  19. 布丁浅谈之Linux常用基本命令
  20. 善于进步的人善于让步

热门文章

  1. hadoop 学习路线
  2. 已解决SyntaxError: invalid syntax
  3. Python运行时,提示SyntaxError: invalid syntax怎么解决
  4. SVN安装步骤【详细】
  5. uniapp 开发微信小程序,通过高德SDK获取当位置详细信息
  6. 【20220207】【信号处理】三次样条插值原理详解
  7. SingleTask和SingleInstance详解
  8. intell idea怎么恢复默认设置
  9. Win11自带的输入法不见了
  10. 大数据实训室课程体系设计案例分享