这个话题是很奇怪,设计模式是引导程序的设计不是模仿什么软件?呃。我的意思是,这是 面“对象”相对的设计模式。

我曾见过有人写《给妻子解释设计模式》,这样的把计算机中的思想与生活相结合固然非常好。人类解决这个问题的思想是相通的,计算机中的非常多思想比方分治、递归、贪心等都能在生活中找到相似的样例。可是。不恰当的样例反而会误导人的思维。造成理解偏差。设计模式本就是类与类之间怎样组织的一套软件设计经验,我们拿软件开发中的实例来解说,会更加准确。

写在前面:


为什么要学设计模式

非常赞同《大话设计模式》一书作者所言:重要的不是你将来会不会用到这些模式,而是通过这些模式让你找到“封装变化”、“对象间松散耦合”、“针对接口编程”的感觉,从而设计出易维护、易扩展、易复用、灵活性好的程序。

曾经读过《HeadFirst 设计模式》这本书对于小白入门非常好,可是当中非常多样例不符合国人的习惯。有些地方读起来非常别扭(比方:木鸭子,披萨连锁店--这个样例太拖沓了。等)当然也有些非常绝妙的样例(比方:星巴克咖啡)

还有秦小波的《设计模式之禅》,我认为此书是国内原创技术书中较好的,但也有些样例不太合适(比方:女娲造人)。

这些设计模式的书为了通俗易懂,尽量以我们生活中的样例为例来讲设计模式,但有时候不恰当的样例会造成我们的理解偏差。

还曾借阅过《大话设计模式》,此书的写作风格轻快(但我一点也不认为风趣幽默),个人非常不喜欢,并且不少样例比較牵强。

(尤其是"学雷锋"的样例。还有"姚明NBA""计划生育"等例)

对于有一定编程经验的程序猿来说。大可不必如此。以编程中的实际问题为例,更加准确恰当。

GoF的《设计模式》就是设计模式的始祖、经典教科书。

其描写叙述严谨。举例恰当。分类组织。是应该重复细读的经典。

网上写设计模式的文章已经非常多了,可是针对GoF《设计模式》的笔记总结,写的认真、精炼的非常少。

此系列文章。是GoF《设计模式》的读书笔记,从中提炼出其精华,掺杂了一些个人的理解和其它书中恰当的样例,可供熟悉设计模式的朋友查阅复习。

欢迎大家一起探讨。

第0部分

面向对象的软件开发过程 :找到相关的对象。以适当的粒度将它们归类,再定义类的接口和继承层次,建立对象之间的基本关系。

你的设计应该对手头的问题有针对性。同一时候对将来的问题和需求也要有足够的通用性。

(拥抱变化)

避免反复设计或尽可能少做反复设计。

什么是设计模式?

设计模式是对被用来在特定场景下解决一般设计问题的类和相互通信的对象的描写叙述。(也就是怎样组织类之间的关系)

设计模式确定了所包括的类和实例,它们的角色协作方式以及职责分配

客户请求(即调用对象的方法)是使对象运行操作的唯一方法,操作又是对象改变内部数据的唯一方法。(类与类之间的交互是通过调用对方的方法来实现的。

面向对象设计最困难的部分是将系统分解成对象集合

由于要考虑很多因素:封装、粒度、依赖关系、灵活性、性能、演化、复用等,它们都影响着系统的分解。而且这些因素通常还是互相冲突的。

设计的很多对象来源于现实世界的分析模型。可是,设计结果所得到的类通常在现实世界中并不存在。比如,描写叙述过程或算法的对象现实中并不存在,但它们却是设计的关键部分。

设计模式帮你确定并不明显的抽象描写叙述这些抽象的对象

接口

在面向对象系统中,接口是主要的组成部分。对象仅仅有通过它们的接口才干与外部交流,假设不通过对象的接口就无法知道对象的不论什么事情,也无法请求对象做不论什么事情。

对象接口与其功能实现是全然分离的,不同对象能够对请求做不同的实现。也就是说,两个有同样接口的对象能够有全然不同的实现。

(面向过程的语言是接口与功能是绑定的,一个接口(函数名)相应一种功能。

当给对象发送请求时。所引起的详细操作既与请求本身有关又与接受对象有关

动态绑定同意你在执行时刻彼此替换有同样接口的对象。这样的可替换性就称为多态(polymorphism)。

类指定了对象的内部数据和表示,也定义了对象所能完毕的操作。

抽象类(abstract class)的主要目的是为它的子类定义公共接口。

1、类继承与接口继承的比較

理解对象的类(class)与对象的类型(type)之间的区别很重要。
一个对象的定义了对象是如何实现的,同一时候也定义了对象的内部状态和操作的实现。

可是对象的类型仅仅与它的接口有关,接口即对象能响应的请求的集合。

一个对象能够有多个类型(有多个接口)。不同类的对象能够有同样的类型(有同样的基类)。

当然。对象的类和类型是有紧密关系的。由于类定义了对象所能运行的操作。也定义了对象的类型。

C++语言的类既指定对象的类型又指定对象的实现。(不像Java有专门的)

理解类继承接口继承之间的区别也十分重要。

类继承依据一个对象的实现定义了还有一个对象的实现。它是代码和表示的共享机制。

接口继承描写叙述了一个对象什么时候能被用来替代还有一个对象。(在C++中。类继承与接口继承在语法上的差别就是:基类是不是虚基类)

由于很多语言并不显式地区分这两个概念,所以easy被混淆。

在C++中,继承既指接口的继承又指实现的继承。C++中接口继承的标准方法是公有继承一个含(纯)虚成员函数的类。C++中纯接口继承接近于公有继承纯抽象类,纯类继承接近于私有继承。

虽然大部分语言并不区分接口继承和实现继承的区别。但使用中人们还是分别对待它们的。

非常多设计模式依赖于这样的区别。比如,责任链模式中的对象必须有一个公共的类型。但普通情况下它们不具有公共的实现。

2、对接口编程而不是对实现编程

类继承是一个通过复用父类功能而扩展应用功能的基本机制。

它同意你依据旧对象高速定义新对象。

当继承被恰当使用时,全部从抽象类导出的类将共享该抽象类的接口。这意味着子类只加入或重定义操作。而没有隐藏父类的操作。这时,全部的子类都能响应抽象类接口中的请求

仅仅依据抽象类中定义的接口来操纵对象有下面优点:

1、 客户无需知道他们使用对象的特定类型,仅仅须对象有客户所期望的接口。

2、 客户无需知道他们使用对象是用什么来实现的。他们仅仅须知道定义接口的抽象类。

这将及大地降低子系统实现之间的互相依赖关系。

面向对象设计的原则:针对接口编程,而不是针对实现编程。

不将变量声明为某个特定的详细类的实例对象。而是让它遵从抽象类所定义的接口

当你不得不在系统的某个地方实例化详细的类(即指定一个特定的实现)时,创建型模式(AbstractFactory, Builder, Factory Method, Prototype, Singleton)能够帮你。

通过抽象对象的创建过程,这些模式提供不同方式以在实例化时建立接口和实现的透明连接。

创建型模式确保你的系统是採用针对接口的方式书写的。而不是针对实现而书写的

运用复用机制

理解对象、接口、类和继承之类的概念对大多数人来说并不难,问题的关键在于如何运用它们写出灵活的、可复用的软件。

设计模式将告诉你如何去做。

1、继承和组合的比較

面向对象系统中功能复用的两种最经常使用技术是类继承和对象组合。

类继承

同意你依据其它类的实现来定义一个类的实现。

(此被称为“白箱复用”,在继承方式中,父类的内部细节对子类可见。破坏了封装性)

类继承在编译时刻就定义了,所以无法在执行时刻改变从父类继承的实现细节。

假设继承下来的实现不适合解决新的问题,则父类必须重写或被其它更合适的类替换。

且子类中的实现与它的父类有如此紧密的依赖关系,以至于父类实现中的不论什么变化必定导致子类发生变化。

这样的依赖关系限制了灵活性并终于限制了复用性。

一个可用的解决方式是仅仅继承抽象类(接口继承),由于抽象类通常提供较少的实现。

对象组合

新的更复杂的功能能够通过组装或组合对象来获得。(此被称为“黑箱复用”,对象的内部细节是不可见的。)

对象组合是通过获得对其它对象的引用而在执行时刻动态定义的。由于对象仅仅能通过接口訪问,所以我们并不破坏封装性。

仅仅要类型一致。执行时刻还能够用一个对象来替代还有一个对象。

优先使用对象组合有助于保持每一个类被封装,并被集中在单个任务上。且系统的行为将依赖于对象间的关系而不是被定义在某个类中。

面向对象设计的第二个原则:优先使用对象组合,而不是类继承。

2、托付

托付(delegation)是一种组合方法,它使组合具有与继承相同的复用能力。

在托付方式下,有两个对象參与处理一个请求,接受请求的对象将操作托付给它的代理者

这类似于子类将请求交给它的父类处理。使用继承时,被继承的操作总能引用接受请求的对象。

(即用父类的方法来处理子类对象)

托付方式为了得到相同的效果,接受请求的对象将自己传给代理人,使代理人的操作能够引用接受请求的对象

【例】

我们能够在窗体类中保存一个矩形类的实例变量来代理矩形类的特定操作,这样窗体类能够复用矩形类的操作,而不必像继承时那样定义成矩形类的子类。一个窗体拥有一个矩形,而不是一个窗体就是一个矩形。

窗体如今必须显式的将请求转发给它的矩形实例。而不是像曾经它必须继承矩形的操作。

以下的图显示了窗体类Window将它的Area操作托付给一个矩形实例:

(箭头线表示一个类对还有一个类实例的引用关系。引用名是可选的。本例为"rectangle")

托付的长处是:它便于执行时刻组合对象操作以及改变这些操作的组合方式。

(假定矩形对象和圆对象有同样类型。我们仅仅需简单的用圆对象替换矩形对象,则得到的窗体就是圆形的。

)

有一些模式使用了托付,比方Stata、Strategy和Visitor。

在Strategy模式中,一个对象将一个特定的请求托付给一个描写叙述运行策略的对象,它是通过改变代理者来改变对象的行为

托付是对象组合的特例(用到了转发)。

它告诉你对象组合作为一个代码复用机制能够替代继承

3、继承和參数化类型(模板)的比較

还有一种功能复用技术(并不是严格的面向对象)是參数化类型(即模板)。

它同意你在定义一个类时,并不指定该类所用到的其它全部类型。

未指定的类型在使用时以參数形式提供。

模板给我们提供了类继承和对象组合外的第三种方法来组合面向对象系统中的行为

很多设计能够使用这三种技术中的不论什么一种来实现。

模板同意你改变所用到的类型,但继承和模板都不能在执行时刻改变。对象组合技术能够在执行时刻改变组合行为,可是它存在间接性。比較低效。

--------------

【附】依赖、关联、聚合和组合之间的差别

  • 依赖(Dependency) 关系是类与类之间的联接。依赖关系表示一个类依赖于还有一个类的定义。比如,一个人(Person)能够买车(car)和房子(House),Person类依赖于Car类和House类的定义,由于Person类引用了Car和House。

    与关联不同的是,Person类里并没有Car和House类型的属性,Car和House的实例是以參量的方式传入到buy()方法中去的。一般而言,依赖关系在Java语言中体现为局域变量、方法的形參,或者对静态方法的调用

  • 关联(Association)关系是类与类之间的联接,它使一个类知道还有一个类的属性和方法。关联能够是双向的。也能够是单向的。

    在Java语言中。关联关系一般使用成员变量来实现。

  • 聚合(Aggregation) 关系是关联关系的一种,是强的关联关系。聚合是总体和个体之间的关系。比如。汽车类与引擎类、轮胎类,以及其他的零件类之间的关系便总体和个体的关系。与关联关系一样,聚合关系也是通过实例变量实现的。

    可是关联关系所涉及的两个类是处在同一层次上的,而在聚合关系中,两个类是处在不平等层次上的,一个代表总体,还有一个代表部分。

  • 组合(Composition) 关系是关联关系的一种,是比聚合关系强的关系。它要求普通的聚合关系中代表总体的对象负责代表部分对象的生命周期,组合关系是不能共享的。代表总体的对象须要负责保持部分对象和存活,在一些情况下将负责代表部分的对象湮灭掉。代表总体的对象能够将代表部分的对象传递给还有一个对象,由后者负责此对象的生命周期。换言之,代表部分的对象在每个时刻仅仅能与一个对象发生组合关系,由后者排他地负责生命周期。部分和总体的生命周期一样。(比方:人与心脏的关系,心脏没了。人也就没了。by-yang)

——摘自《Java面向对象编程》

UML中对象的关系都是在对应的软件环境或实际场景下定义的,这里差别聚合和组合的关系,关键还是在于它们之中总体和部分的关系强、弱,以及它们之间的依附关系。

在C++中,在语法层面。关联、聚合、组合是没有什么差别的,它们是由你的意图而不是由显式的语言机制决定的。

--------------

组织编目

设计模式在粒度和抽象层次上各不同样。因为存在众多的设计模式。我们希望用一种方式将它们组织起来。

范围\目的

Creational (创建型)

Structural (结构型)

Behavioural (行为型)

Simple Factory

Adapter (class)

Interpreter

Factory Method

Template method

对象

Abstract Factory

Adapter (object)

Chain of Responsibility

Builder

Bridge

Command

Prototype

Composite

Iterator

Singleton

Decorator

Mediator

Facade

Memento

Flyweight

Observer

Proxy

State

Strategy

Visitor

我们在两个维度上对模式进行分类。

第一是目的准则。即模式是用来完毕什么工作的。模式根据其目的可分为创建型结构型行为型

创建型模式与对象的创建有关;结构型模式处理类或对象的组合行为型模式对类或对象如何交互和如何分配职责进行描写叙述。

第二是范围准则。即模式主要是用于类还是用于对象类模式处理类和子类之间的关系。这些关系通过继承建立。是静态的,在编译时刻便确定下来了。

对象模式处理对象间的关系,这些关系在执行时刻是能够变化的,更具动态性。

创建型类模式,将对象的部分创建工作延迟到子类,而创建型对象模式则将它延迟到还有一个对象中。

结构型类模式,使用继承机制来组合类。而结构型对象模式则描写叙述了对象的组装方式。

行为型类模式。使用继承描写叙述算法和控制流,而行为型对象模式则描写叙述一组对象如何协作完毕单个对象所无法完毕的任务。

封装变化。是很多设计模式的主题。

版权声明:本文博客原创文章,博客,未经同意,不得转载。

猿取向的规划设计模式 ——GoF《设计模式》阅读摘要(零)相关推荐

  1. sql中如何统计各种零件的总数量_如何应用GOF设计模式中的构建者模式创建复合对象实例...

    软件项目实训及课程设计指导--如何应用GOF设计模式中的构建者模式创建复合对象实例 1.GOF设计模式中的构建者模式 构建者设计模式能够将一个复杂对象(它一般为组合类)的构建过程与它的表示部件相互分离 ...

  2. 函数式编程会取代GoF设计模式吗?

    自从我去年开始学习F#和OCaml以来,我已经阅读了大量文章,这些文章坚持认为设计模式(尤其是Java语言)是命令式语言中缺少功能的变通方法. 我发现一篇文章提出了相当有力的主张 : 我遇到的大多数人 ...

  3. 用 Kotlin 的函数式编程 替代 GOF 设计模式

    用 Kotlin 的函数式编程 替代 GOF 设计模式 函数式编程(FP) <Kotlin极简教程>正式上架: 点击这里 > 去京东商城购买阅读 点击这里 > 去天猫商城购买阅 ...

  4. GoF设计模式读书笔记

    花了大概一天时间,把大名鼎鼎的GoF的设计模式看完了.内容很丰富,被如今封为准则的23种设计模式在这本书里面娓娓道来. 正如该书前沿所述,这本书事实上并不是一本适合从头读到尾的书,而是一本类似于手册, ...

  5. GOF设计模式学习--辨析各种模式的要点和相似模式之间的区别

    --辨析各种模式的要点和相似模式之间的区别 http://blog.csdn.net/wind19/article/details/6968149 1                    正文之前 ...

  6. Java设计模式GOF之6大设计原则

    Java设计模式GOF之6大设计原则原则 1.开闭原则(Open Close Principle) 一个软件实体如类.模块和函数应该对扩展开放,对修改关闭. 开闭原则是面向对象的可复用设计的第一块基石 ...

  7. (转):GOF设计模式趣解(23种设计模式)

    GOF设计模式趣解(23种设计模式) 创建型模式 1.FACTORY--追MM少不了请吃饭了,麦当劳的鸡翅和肯德基的鸡翅都是MM爱吃的东西,虽然口味有所不同,但不管你带MM去麦当劳或肯德基,只管向服务 ...

  8. GoF设计模式(二)-行为型模式简介

    文章目录 复用决策与扩展决策的行为 由具体子类决定 Template 模板行为 由其他类的对象决定 Strategy 策略(库)行为 State 状态(机)行为 由具体子类决定与其他类的对象决定 Vi ...

  9. [设计模式] GoF 23种经典设计模式

    原文链接:https://www.yuque.com/cppdev/patterns/zainii 「GOF设计模式」Gang of Four,四人帮.设计模式的经典书籍<设计模式--可复用面向 ...

  10. 总结:GoF设计模式及应用

    2019独角兽企业重金招聘Python工程师标准>>> GoF设计模式 Christopher Alexander 说过:"每一个模式描述了一个在我们周围不断重复发生的问题 ...

最新文章

  1. centos输入正确的账号和密码登陆不进去
  2. 自助建站软件越来越友好,三大优点值得用心体会
  3. Windows Azure Camp---漫步云端,创意无限
  4. DL之DNN:利用DNN【784→50→100→10】算法对MNIST手写数字图片识别数据集进行预测、模型优化
  5. mysql端口被占用_MySQL重启端口被占用处理
  6. 使用Python为《围城》做一个图云
  7. Wpf之元素绑定元素属性
  8. 创新、协调、绿色、开放、共享”五大发展理念整体上是一个彼此之间有联系、成结构的体系,是统一的,而从个体上来说,他们之间是相互促进、相互依赖、相互作用、相互对立的,这恰恰体现出辩证法物质世界的普遍联系和
  9. 数组元素全排列、组合 C语言代码
  10. CC控制服务的设计和侦测方法综述
  11. python 实例解析--村长选举
  12. android 版本升级 解析包出问题怎么解决方案,Android 7.0解析包时出现问题 的解决方案(应用内更新)...
  13. 1688电商API接口-无需多个 电商平台单独对接
  14. 四舍六入五留双与四舍五入之间的差别
  15. 【2020.12】Aspose.words 20.12最新版Crack,word转pdf去水印方法
  16. 小两口吵架 摔什么东西最划算?
  17. c#和python哪个效率高_【为什么C#排名和Python相差越来越大?】-看准网
  18. 尚硅谷 宋红康 JVM教程_02_字节码与类的加载篇
  19. 虹科方案|数据流智能分析软件-数据的转换与协调
  20. oracle课后体会,今日学习Oracle心得体会

热门文章

  1. 关于html5中a链接的download属性
  2. matlab中结构体使用方法
  3. matlab图片集成成视频
  4. Android中关于键盘的处理
  5. UITableView分割线
  6. NOIP引水入城(dfs)
  7. JS字符串截取(获取指定字符后面的所有字符内容)
  8. 如何应用Java的静态内部类
  9. Streams AQ: qmn coordinator waiting for slave to start等待事件
  10. 如何清除vsphere主机提示“此主机当前没有管理网络冗余”