登入帳戶  | 訂單查詢  | 購物車/收銀台( 0 ) | 在線留言板  | 付款方式  | 運費計算  | 聯絡我們  | 幫助中心 |  加入書簽
會員登入 新用戶登記
HOME新書上架暢銷書架好書推介特價區會員書架精選月讀2023年度TOP分類瀏覽雜誌 臺灣用戶
品種:超過100萬種各類書籍/音像和精品,正品正價,放心網購,悭钱省心 服務:香港台灣澳門海外 送貨:速遞郵局服務站

新書上架簡體書 繁體書
暢銷書架簡體書 繁體書
好書推介簡體書 繁體書

三月出版:大陸書 台灣書
二月出版:大陸書 台灣書
一月出版:大陸書 台灣書
12月出版:大陸書 台灣書
11月出版:大陸書 台灣書
十月出版:大陸書 台灣書
九月出版:大陸書 台灣書
八月出版:大陸書 台灣書
七月出版:大陸書 台灣書
六月出版:大陸書 台灣書
五月出版:大陸書 台灣書
四月出版:大陸書 台灣書
三月出版:大陸書 台灣書
二月出版:大陸書 台灣書
一月出版:大陸書 台灣書

『簡體書』Objective-C编程之道:iOS设计模式解析(解析iOS设计模式的开山之作)

書城自編碼: 1815501
分類:簡體書→大陸圖書→計算機/網絡程序設計
作者: [美]Carlo
國際書號(ISBN): 9787115265869
出版社: 人民邮电出版社
出版日期: 2011-11-01
版次: 1 印次: 1
頁數/字數: 297/455000
書度/開本: 16开 釘裝: 平装

售價:HK$ 174.1

我要買

 

** 我創建的書架 **
未登入.


新書推薦:
故事力:TED演讲者助力,当代青年克服表达难题(两位TED专业讲者教你掌握故事五大力)
《 故事力:TED演讲者助力,当代青年克服表达难题(两位TED专业讲者教你掌握故事五大力) 》

售價:HK$ 81.6
中国民间神话故事绘(套装共15册)
《 中国民间神话故事绘(套装共15册) 》

售價:HK$ 456.0
无限可能的身体
《 无限可能的身体 》

售價:HK$ 72.0
中国人工智能系列研究报告:大型语言模型的教育应用
《 中国人工智能系列研究报告:大型语言模型的教育应用 》

售價:HK$ 69.6
北洋大学与近代中国(第2辑)
《 北洋大学与近代中国(第2辑) 》

售價:HK$ 153.6
汗青堂丛书048·科举史(新)
《 汗青堂丛书048·科举史(新) 》

售價:HK$ 79.2
新形势下海事综合风险管控理论与实践
《 新形势下海事综合风险管控理论与实践 》

售價:HK$ 96.0
数码港元:Web3.0构建香港新金融
《 数码港元:Web3.0构建香港新金融 》

售價:HK$ 90.0

 

建議一齊購買:

+

HK$ 127.7
《 Swifter(第2版):100个Swift 2 开发必备Tip 》
+

HK$ 218.3
《 精通iOS开发(第7版) 》
+

HK$ 109.2
《 编写高质量代码:改善Objective-C程序的61个建议 》
+

HK$ 146.2
《 iOS应用逆向工程 第2版 》
+

HK$ 179.4
《 Effective Objective-C 2.0:编写高质量iOS与OS X代码的52个有效方法(名著名译,Amazon五星好评,7大方面探讨编写高效、易于理解易于维护和易于扩展的Objective-C代码) 》
+

HK$ 209.4
《 iOS 6开发进阶与实战 》
編輯推薦:
·解析iOS设计模式的开山之作
·优化Objective-C编程实践的必修宝典
·由此迈入移动开发高手行列
內容簡介:
《Objective-C编程之道:iOS设计模式解析》是基于iOS的软件开发指南。书中应用GoF的经典设计模式,介绍了如何在代码中应用创建型模式、结构型模式和行为模式,如何设计模式以巩固应用程序,并通过设计模式实例介绍MVC在CocoaTouch框架中的工作方式。
《Objective-C编程之道:iOS设计模式解析》适用于那些已经具备Objective-C基础、想利用设计模式来提高软件开发效率的中高级iOS开发人员。
關於作者:
Carlo Chung(钟冠贤) 计算机科学家,喜欢摆弄机器、爱好摄影。他拥有计算机科学硕士学位,专业方向是计算机视觉(人工智能的分支)。把人工智能与任何小装置结合起来的想法都能令他兴奋不已。他常常梦想着让iPhone变得更智能、更像人,曾把计算机视觉的知识应用到iPhone平台并开发了几个应用,有两个被作为特色应用出现在App Store首页,其中有一个还被列为摄影类别中的最佳付费应用(Top Paid)。
目錄
目 录
第一部分 设计模式初体验
第1章 你好,设计模式 2
1.1 这是一本什么书 2
1.2 开始前的准备 2
1.3 预备知识 3
1.4 似曾相识的设计 3
1.5 设计模式的起源——模型、视图和控制器 4
1.5.1 在模型对象中封装数据和基本行为 4
1.5.2 使用视图对象向用户展示信息 5
1.5.3 用控制器对象联系起模型和视图 5
1.5.4 作为复合设计模式的MVC 5
1.6 影响设计的几个问题 6
1.6.1 针对接口编程,而不是针对实现编程 7
1.6.2 @protocol与抽象基类 7
1.6.3 对象组合与类继承 8
1.7 本书用到的对象和类 9
1.7.1 类图 9
1.7.2 对象图 12
1.8 本书如何安排模式的讲解 13
1.9 总结 13
第2章 案例分析:设计一个应用程序 14
2.1 想法的概念化 14
2.2 界面外观的设计 15
2.3 架构设计 17
2.3.1 视图管理 18
2.3.2 如何表现涂鸦 20
2.3.3 如何表现保存的涂鸦图 24
2.3.4 用户操作 27
2.4 所用设计模式的回顾 32
2.5 总结 33
第二部分 对象创建
第3章 原型 36
3.1 何为原型模式 36
3.2 何时使用原型模式 37
3.3 浅复制与深复制 38
3.4 使用Cocoa Touch框架中的对象复制 39
3.5 为Mark聚合体实现复制方法 39
3.6 将复制的Mark用作“图样模板” 47
3.7 总结 49
第4章 工厂方法 50
4.1 何为工厂方法模式 50
4.2 何时使用工厂方法 51
4.3 为何这是创建对象的安全方法 51
4.4 在TouchPainter中生成不同画布 51
4.5 在Cocoa Touch框架中应用工厂方法 57
4.6 总结 58
第5章 抽象工厂 59
5.1 把抽象工厂应用到TouchPainter应用程序 60
5.2 在Cocoa Touch框架中使用抽象工厂 66
5.3 总结 68
第6章 生成器 69
6.1 何为生成器模式 69
6.2 何时使用生成器模式 70
6.3 构建追逐游戏中的角色 71
6.4 总结 79
第7章 单例 80
7.1 何为单例模式 80
7.2 何时使用单例模式 81
7.3 在Objective-C中实现单例模式 81
7.4 子类化Singleton85
7.5 线程安全 85
7.6 在Cocoa Touch框架中使用单例模式 86
7.6.1 使用UIApplication类 86
7.6.2 使用UIAccelerometer类 86
7.6.3 使用NSFileManager类 86
7.7 总结 87
第三部分 接口适配
第8章 适配器 90
8.1 何为适配器模式 90
8.2 何时使用适配器模式 92
8.3 委托 92
8.4 用Objective-C协议实现适配器模式 93
8.5 用Objective-C的块在iOS 4中实现适配器模式 99
8.5.1 块引用的声明 99
8.5.2 块的创建 100
8.5.3 把块用作适配器 100
8.6 总结 104
第9章 桥接 105
9.1 何为桥接模式 105
9.2 何时使用桥接模式 106
9.3 创建iOS版虚拟仿真器 106
9.4 总结 112
第10章 外观 113
10.1 何为外观模式 113
10.2 何时使用外观模式 114
10.3 为子系统的一组接口提供简化的接口 114
10.4 在TouchPainter应用程序中使用外观模式 117
10.5 总结 119
第四部分 对象去耦
第11章 中介者 122
11.1 何为中介者模式 122
11.2 何时使用中介者模式 124
11.3 管理TouchPainter应用程序中的视图迁移 124
11.3.1 修改迁移逻辑的困难 126
11.3.2 集中管理UI交通 127
11.3.3 在Interface Builder中使用CoordinatingController 132
11.4 总结 135
第12章 观察者 136
12.1 何为观察者模式 136
12.2 何时使用观察者模式 138
12.3 在模型-视图-控制器中使用观察者模式 138
12.4 在Cocoa Touch框架中使用观察者模式 138
12.4.1 通知 139
12.4.2 键-值观察 139
12.5 在TouchPainter中更新CanvasView上的线条 140
12.6 总结 149
第五部分 抽象集合
第13章 组合 152
13.1 何为组合模式 152
13.2 何时使用组合模式 154
13.3 理解TouchPainter中Mark的使用 154
13.4 在Cocoa Touch框架中使用组合模式 163
13.5 总结 164
第14章 迭代器 165
14.1 何为迭代器模式 165
14.2 何时使用迭代器模式 167
14.3 在Cocoa Touch框架中使用迭代器模式 167
14.3.1 NSEnumerator 167
14.3.2 基于块的枚举 168
14.3.3 快速枚举 169
14.3.4 内部枚举 170
14.4 遍历Scribble的顶点 170
14.5 总结 178
第六部分 行为扩展
第15章 访问者 180
15.1 何为访问者模式 180
15.2 何时使用访问者模式 182
15.3 用访问者绘制TouchPainter中的Mark 182
15.4 访问者的其他用途 189
15.5 能不能用范畴代替访问者模式 189
15.6 总结 189
第16章 装饰 190
16.1 何为装饰模式 190
16.2 何时使用装饰模式 191
16.3 改变对象的“外表”和“内容” 192
16.4 为UIImage创建图像滤镜 192
16.4.1 通过真正的子类实现装饰 193
16.4.2 通过范畴实现装饰 201
16.5 总结 206
第17章 责任链 207
17.1 何为责任链模式 207
17.2 何时使用责任链模式 208
17.3 在RPG游戏中使用责任链模式 209
17.4 总结 214
第七部分 算法封装
第18章 模板方法 216
18.1 何为模板方法模式 216
18.2 何时使用模板方法 217
18.3 利用模板方法制作三明治 217
18.4 保证模板方法正常工作 224
18.5 向模板方法增加额外的步骤 225
18.6 在Cocoa Touch框架中使用模板方法 228
18.6.1 UIView类中的定制绘图 228
18.6.2 Cocoa Touch框架中的其他模板方法实现 228
18.7 总结 229
第19章 策略 230
19.1 何为策略模式 230
19.2 何时使用策略模式 231
19.3 在UITextField中应用验证策略 231
19.4 总结 239
第20章 命令 240
20.1 何为命令模式 240
20.2 何时使用命令模式 241
20.3 在Cocoa Touch框架中使用命令模式 241
20.3.1 NSInvocation对象 242
20.3.2 NSUndoManager 242
20.4 在TouchPainter中实现撤销与恢复 243
20.4.1 使用NSUndoManager实现绘图与撤销绘图 244
20.4.2 自制绘图与撤销绘图的基础设施 248
20.4.3 允许用户触发撤销与恢复 255
20.5 命令还能做什么 256
20.6 总结 257
第八部分 性能与对象访问
第21章 享元 260
21.1 何为享元模式 260
21.2 何时使用享元模式 262
21.3 创建百花池 262
21.4 总结 269
第22章 代理 270
22.1 何为代理模式 270
22.2 何时使用代理模式 271
22.3 用虚拟代理懒加载图像 272
22.4 在Cocoa Touch框架中使用代理模式 277
22.5 总结 279
第九部分 对象状态
第23章 备忘录 282
23.1 何为备忘录模式 282
23.2 何时使用备忘录模式 283
23.3 在TouchPainter中使用备忘录模式 284
23.3.1 涂鸦图的保存 284
23.3.2 涂鸦图的恢复 285
23.3.3 ScribbleMemento的设计与实现 286
23.4 Cocoa Touch框架中的备忘录模式 295
23.5 总结 297
內容試閱
你好,设计模式
几乎每一本讲计算机编程的书开篇都是以“你好,世界!”(Hello,
World!)一章来介绍主题。由于这是一本关于设计模式的书,我们就从“你好,设计模式”开始吧。
既然你已经拿起了这本书,对于面向对象编程中设计模式的概念,你也许已经熟悉。设计模式是有用的抽象化工具,用于解决工程和建筑等其他领域的设计问题。出于同样的目的,软件开发领域借用了这一概念。设计模式是一个对象或类的设计模板,用于解决特定领域经常发生的问题。
本章介绍设计模式的简史,以及设计模式与Cocoa
Touch技术之间的关系。不仅讨论了影响设计的若干问题,还介绍了本书用到的对象图示法,以及本书如何安排设计模式。
1.1 这是一本什么书
本书写给想通过使用设计模式以使软件开发更高效、更有趣的专业人员和有抱负的iOS开发人员。本书的目的在于,展示如何将设计模式在iOS的应用开发中付诸实践。我会集中讨论各种设计模式对于Cocoa
Touch框架及其相关技术的适用性。
尽管本书介绍的有些原则和概念可能也适用于Cocoa Touch的老大哥——Mac OS
X的Cocoa,但是不保证它们完全适用于完整版的Cocoa。另外,本书还可以用做Objective-C设计模式的快速参考手册。
你将会学到:
? 各种设计模式的基本概念;
? 在各种设计场景,如何将设计模式应用到代码中;
? 设计模式如何增强应用程序。
本书的网站是www.objective-c-design-patterns.com或www.objectivecdesignpatterns.com。欢迎分享你在项目中使用设计模式的成功事例以及遇到的困难。
书中的源代码可从www.apress.com下载。
1.2 开始前的准备
同其他讲iOS应用程序开发的书一样,你需要Xcode和iOS
SDK来运行本书中的示例代码。本书的示例项目的编译和测试使用的是Xcode 3.2.5和iOS SDK
4.2,应该也可以使用更高版本。有许多免费或付费的非Mac OS
X平台的工具可以开发iOS应用程序,但是不保证本书中的示例程序在这些平台也能正常运行。
本书也涉及了iOS应用程序设计的一些内容。你可能需要下载或购买一些软件工具来帮助构建线框图和UI布局,用以练习或设计实际的应用程序。本书中的线框图是用OmniGraffle(www.omnigroup.comproductsomnigraffle)制作的。该网站还提供了各种免费模板(stencil)和线框模板的下载。
本书中大量使用了类和对象图,但是可用的类和对象的建模工具软件却很少。本书写作的时候,多数建模软件基于标准图示法,而这些标准图示法只适用于C++、Java和C#等其他面向对象编程语言。Objective-C有一些特殊功能,比如范畴(category)和扩展(匿名范畴),难以用标准图示法来表达。因此,为了表达这些特殊的功能,我新造了若干图示法。在本章稍后的1.7节中将予以介绍。可以用你的绘图软件根据这些新造的图示法来绘制Objective-C的类和对象。希望适用于Objective-C的标准化对象建模图示法尽早面世。
1.3 预备知识
本书属于专业丛书,所以并不是“iOS开发基础”或“Objective-C 24小时入门”。读者应具有iOS SDK(Cocoa
Touch框架)的基础知识。此外,读者也应对Objective-C编程语言有足够的了解。否则,将无法理解本书中的很多观点和高级技巧。
尽管本书主要面向中高级开发人员,但读者并不需要对设计模式有深入的了解就能理解设计模式的概念。即便你已经在工作中接触过一些设计模式,你仍可从本书获益。介绍模式的所有章节都借助打比方,让读者对设计模式能有透彻的理解。而且,不易理解之处会有提示和说明。
准备好了吗?我们开始吧!
1.4 似曾相识的设计
身为开发人员,你可能有过这样的感受:“我以前解决过这个问题,但不记得具体是在哪里、怎样解决的。”经常会有这样的事儿,要是你重复做着特定类型的项目更是如此。比如,数据库的应用程序都有存储和检索数据的数据库访问功能。你要是记录下问题的细节和解决方法,就可以复用这些方法,而不是次次从零开始。
有关设计中最常见的似曾相识的情况以及解决方法,最早作出权威性论述和分类的是《设计模式》(Erich Gamma、Richard
Helm、Ralph Johnson和John Vlissides著,Addison- Wesley
Professional出版社,1994年)。该书将设计面向对象软件的经验总结为可以有效使用的设计模式。有趣的是,Cocoa(Touch)框架的前身NEXTSTEP的设计中采用了很多漂亮、可复用的面向对象软件设计模式,而这对激发GoF(该书作者为人熟知的绰号)的灵感起到了重要作用。
根据《设计模式》一书,设计模式是对定制来解决特定场景下一般设计问题的类和相互通信的对象的描述。
简而言之,设计模式是为特定场景下的问题而定制的解决方案。特定场景指问题所在的重复出现的场景。问题指特定环境下你想达成的目标。同样的问题在不同的环境下会有不同的限制和挑战。定制的解决方案是指在特定环境下克服了问题的限制条件而达成目标的一种设计。
设计模式是经时间证明为有效的,对特定面向对象设计问题主要方面的一种抽象,体现了面向对象设计的重要思想。有些设计原则影响着设计模式。这些原则是构建可复用、可维护的面向对象应用程序的经验法则,比如,“优先使用对象组合而不是类继承”和“针对接口编程而不是针对实现编程”。
例如,通过给程序的变动部分定义接口而对其封装和隔离,这些部分的变动就独立于程序的其他部分,因为它们不依赖于任何细节。以后就可以变更或扩展这些可变的部分而不影响程序的其他部分。程序将因此能够更灵活而可靠地进行变更,因为我们消除了部分与部分之间的依赖关系并减少了耦合。这些益处使得设计模式对于可复用软件的编写非常重要。
程序(包括其中的对象和类),如果在设计中使用了设计模式,将来就更易于复用与扩展,更易于变更。而且,基于设计模式的程序会更加简洁而高效,因为达成同样目的所需的代码行会更少。
1.5 设计模式的起源——模型、视图和控制器
模型?视图?控制器(MVC)设计模式及其变体至少在Smalltalk诞生初期就已经出现了。这个设计模式是Cocoa
Touch中很多机制和技术的基础。
在MVC设计模式中,对象在应用程序中被分为三组,分别扮演模型、视图和控制器。MVC模式也定义了对象之间跨越其角色的抽象边界的通信方式。MVC对Cocoa
Touch应用程序设计起了重要作用。应用程序设计的一个主要步骤是决定对象或类应该属于这三组中的哪一组。如果应用程序的MVC划分得清晰,使用Cocoa
Touch框架中的任何技术都会相对容易。
这个模式本身不是独立的模式,而是由几个其他基本模式组成的复合模式。这些基本模式将在本书介绍模式的章节中详细介绍。
相比于非MVC的应用程序,MVC的应用程序中的对象更加易于扩展和复用,因为其接口通常会定义得更好。而且,许多Cocoa
Touch技术和架构是建立在MVC之上的,要求应用程序和对象服从于给MVC的角色设定的规则。
后面几节将阐述MVC中的各个角色在架构中如何发挥其作用。
1.5.1 在模型对象中封装数据和基本行为
模型对象维护应用程序的数据,并定义操作数据的特定逻辑。模型对象可以复用,因为它表示的知识适用于特定的问题领域。例如,模型对象可以表示复杂的数据结构,对应于用户在屏幕上所画的图形,或者仅仅表示待办事项应用程序中的一条待办事项。
只要加载的是包含有应用程序永久信息的数据,就应将其放入模型对象。理想状况下,模型对象同用于对其进行显示和编辑的用户界面之间不应有任何直接的关联。
1.5.2 使用视图对象向用户展示信息
视图对象可以响应用户操作,并懂得如何将自己展现在屏幕上。视图对象通常从应用程序的模型对象获取数据用以展示。它可以跟一个模型对象的部分、整体或者多个模型对象合作。通常,用户可以通过它修改数据。
虽然视图对象和模型对象之间关系密切,但是在MVC应用程序中它们之间没有耦合。除非因性能原因(比如视图需要对数据进行缓存),不应将视图用于存储它所展示的数据。
因为视图对象可以与许多不同的模型对象合作,所以它们往往可在不同应用程序之间复用并保持一致。UIKit框架提供了各种类型的视图类,可复用于我们的应用程序。
1.5.3 用控制器对象联系起模型和视图
控制器对象就像视图对象和模型对象的中间人。作为中间人或协调人,它建立起沟通渠道,使视图得以知晓模型的变更而给予响应。
除了协调作用之外,控制器对象还可以为应用程序执行其他操作,比如为应用程序管理其他对象的生命周期,进行设置和协调任务。
举例来说,用户通过操作视图对象(比如在文本框中输入)得到的值,可以传给控制器对象。控制器对象也可以让视图对象根据此用户操作改变其外观或行为,比如禁用某个文本输入框。
依照所需的设计,控制器对象可设计为可复用的或不可复用的(具体的 )。
1.5.4 作为复合设计模式的MVC
MVC本身并不是最基本的设计模式,它包含了若干更加基本的设计模式,这些模式将在本书的模式章节中阐述。在MVC中,基本设计模式相互配合,确定了各功能之间的协作,这是MVC应用程序的特性。
Cocoa(Touch)的MVC用到的模式有:组合(Composite)、命令(Command)、中介者(Mediator)、策略(Strategy)和观察者(Observer)。
?
组合(第13章)——视图对象之间以协作的方式构成一个视图层次体系,其中既可以有复合视图(比如表格视图),也可以有独立视图(比如文本框或按钮)。每个层次的每个视图节点都可以响应用户的操作并把自己绘制到屏幕上。
?
命令(第20章)——这是一种“目标?动作”机制,视图对象可以推迟其他对象(比如控制器)的执行,让其他对象等到发生了某些事件后再执行。这一机制构成了命令模式。
?
中介者(第11章)——控制器对象起着中间人的作用,而这个中间人则采用了中介者模式,它构成了在模型和视图对象之间传递数据的双向通道。应用程序的控制器对象将模型的变更传达给视图对象。
?
策略(第19章)——控制器可以是视图对象的一个“策略”。视图对象将自身隔离,以期维持其作为数据展示器的唯一职责,而将一切应用程序特有的界面行为的决定委派给它的“策略”对象(即控制器)。
? 观察者(第12章)——模型对象向它所关注的控制器等对象发出内部状态变化的通知。
图1-1展示了虚构场景下这些模式是如何协同工作的。
图1-1 展示模型、视图和控制器作为一组不同的实体如何交互的示意图
在图1-1中,
1
用户在画布视图上用手指触摸或拖动,产生一个触摸事件。被触摸的实际视图(图层)就在视图组合中的某个层次上。画布(视图)将触摸消息传达给视图控制器。
2
控制器对象接收到触摸事件及其相关信息,然后应用策略来变更模型的状态,必要时请求视图对象根据此事件更新其行为或外观。
3 每当变更发生并已反映到模型对象,模型对象就会通知所有已注册的观察者对象,如控制器。
4 控制器就像一个协调人,它将变更了的数据从模型传递给视图,以便视图可以相应地更新其外观。
1.6 影响设计的几个问题
设计模式肯定会从许多方面影响系统设计。但是有一些设计原则也会影响设计。有些原则针对一般的软件设计,而有些原则是针对Objective-C和Cocoa
Touch的。我将在以下各节进行讨论。
1.6.1 针对接口编程,而不是针对实现编程
很多软件开发人员理解类、对象、继承、多态和接口这些面向对象概念。可是类继承与接口继承(子类型化)的区别何在?接口定义了类型,接口继承(子类型化)让我们可以用一个对象代替另一个对象。另一方面,类继承是通过复用父类的功能或者只是简单地共享代码和表述,来定义对象的实现和类型的一种机制。类继承让我们能够从现成的类继承所需大部分功能,从而快速定义新的类。其实,类和类型关系非常密切。不过,差别在于一个对象可以具有多种类型而不同类的对象可以有相同的类型。
定义具有相同接口的类群很重要,因为多态是基于接口的。其他面向对象的编程语言,如Java,允许开发者定义“接口”(区别于类)类型,它确定了客户端同所用的具体类之间的一种“合约”。Objective-C中有一种类似的东西叫做协议(protocol)。协议也是对象之间的一种合约,但本身不能实例化为对象。实现协议或者从抽象类继承,使得对象共享相同的接口(1.6.2节将讨论有关使用协议和抽象基类的问题)。因此,子类型的所有对象,都可以对针对协议或抽象类的接口的请求作出应答。
这样做有以下两点好处:
? 只要对象符合客户端所要求的接口,客户端就不必在意所使用对象的确切类型;
? 客户端只知道定义接口的协议或者抽象类,因此客户端对对象的类一无所知。
这就得出了GoF在书中所说的可复用面向对象软件设计的原则:
针对接口编程,而不是针对实现编程。
通常的做法是,在客户端的代码中不声明特定具体类的变量,而只使用协议或抽象类定义的接口。这种概念和思想贯穿本书。
1.6.2 @protocol与抽象基类
嗯,应该针对接口编程,而不是针对实现编程。但是,要针对什么样的接口呢?在Objective-C中,有一种称为协议的语言功能(语法为@protocol)。协议并不定义任何实现,而只声明方法(method),以确定符合协议的类的行为。因此协议是只定义了抽象行为的“接口”。实现协议的类定义这些方法的实现,以执行真正的操作。另一种定义高度抽象类型的方法是定义抽象基类(Abstract
Base
Class,ABC)。通过抽象基类,我们可以生成一些其他子类可以共享的默认行为。抽象基类与通常的类相似,只是预留了一些可以或应该由子类重载的行为。
变更过去定义的协议可能会破坏实现该协议的类。协议(或接口)是抽象类型与具体类型之间的一种合约。如果变更合约,所有相关的事项也需要变更。唯一例外是,只使用@optional指令(directive)将协议的部分方法变更为“可选的”。而抽象基类在接口变更方面要稍微灵活一些。我们可以向抽象基类随意追加新的方法,而不会破坏继承链的其他部分。而且,对于子类可能用到的占位方法(stubbed-out
method)中定义的默认行为,我们可以随意地进行追加、删除或分解。
客户端如果要使用由协议所定义类型的对象,比方说有个协议叫Mark,则需要使用以下语法来引用它:
id thisMark;
如果Mark被声明为抽象基类,那么语法应该跟其他类一样,如下所示:
Mark *thisMark;
在接受以Mark协议的对象作为参数的方法中,语法应该是这样:
- void anOperationWithMark:id aMark;
如果Mark是抽象基类,那么语法是这样:
- void anOperationWithMark:Mark * aMark;
哪个看上去更好呢?很明显,Mark协议的引用显得有点儿笨拙。那么为什么还要使用协议呢?一个主要原因是,Objective-C与C++等其他面向对象语言不同,它不支持多重继承。如果一个类既要是UIView的子类,同时又要是定制的抽象类型,那么这个抽象类型就只能是协议而不能是抽象基类。只对一个抽象类型进行子类化的类,可以让它们直接对抽象基类进行子类化。
但是也许你以后会更改设计,以使抽象类型也能够是UIView
等的子类。能否两全其美?通常这种情况下灵活的做法是,首先为不需要子类化其他类的类定义一个抽象基类,然后可以定义一个同名协议,让包括这个抽象基类在内的其他类去实现。在Cocoa
Touch框架中你会发现类似的策略,例如,NSObject基类符合NSObject协议。
1.6.3 对象组合与类继承
类继承或子类化让我们可以使用其他的类来定义类的实现。子类化常常被称为白箱复用(white-box
reuse),因为父类的内部描述与细节通常对子类可见。
对象组合可以替代类继承。对象组合要求被组合的对象具有定义良好的接口,并且通过从其他对象得到的引用在运行时动态定义。所以可以将对象组合到其他对象中,以构建更加复杂的功能。由于对象的内部细节对其他对象不可见,它们看上去为“黑箱”,这种类型的复用称为黑箱复用(black-box
reuse)。
使用类继承和对象组合的白箱和黑箱复用各有其优缺点。以下是对类继承的一些优缺点的总结。
优点是:
? 类继承简单直接,因为关系在编译时静态定义;
? 被复用的实现易于修改。
缺点是:
? 因为类继承在编译时定义,所以无法在运行时变更从父类继承来的实现;
? 子类的部分描述常常定义在父类中;
? 子类直接面对父类实现的细节,因此破坏了封装;
? 父类实现的任何变更都会强制子类也进行变更,因为它们的实现联系在了一起;
? 因为在新的问题场景下继承来的实现已过时或不适用,所以必须重写父类或继承来的实现。
由于实现的依存关系,对子类进行复用可能会有问题。有一个解决办法是,只从协议或抽象基类继承(子类型化),因为它们只有很少的实现,而协议则没有实现。
对象组合让我们同时使用多个对象,而每个对象都假定其他对象的接口正常运行。因此,为了在系统中正常运行,它们的接口都需要经过精心的设计。然而,对象组合也有其优缺点应予考虑。
优点是:
? 不会破坏封装,因为只通过接口来访问对象;
? 大大减少实现的依存关系,因为对象的实现是通过接口来定义的;
? 可以在运行时将任意对象替换为其他同类型的对象;
? 有助于保持类的封装以专注于单一任务;
? 类及其层次结构能保持简洁,不至于过度膨胀而无法管理。
缺点是:
? 设计中涉及较多对象;
? 系统的行为将依赖于不同对象间的关系,而不是定义于单个类中;
?
理想情况下,不需要创建新的组件就能实现复用;十分罕见的情况是,通过对象组合的方式,仅仅对已有的组件进行组合就能得到所需的全部功能;实际上,现成的组件总是不太够用。
尽管有以上缺点,对象组合仍然对系统设计有诸多好处。我们可以通过在某些部分使用类继承来克服这些缺点,使得利用已有组件创建新的组件较为容易。
优先使用对象组合而不是类继承,并不是说完全不使用类继承。需要根据具体情况对如何复用类和对象作出清晰的判断。如果系统设计得合理,类继承与对象组合可以相互配合。设计类时,通常倾向于考虑对象组合。然后寻找出冗余行为,进行设计细化。如果找到冗余行为,也许意味着此处应该使用类继承。在本书对设计模式的讨论中会谈到对象组合。
1.7 本书用到的对象和类
本书使用各种图形、图表来解释模式的一些重要思想。有时会使用屏幕截图或视觉表现来展示诸如组合树之类对象的结构。但是我需要更加正式而清楚的方法,来表达类与对象间的关系和相互作用。贯穿于本书中模式的最常用的图示法是类和对象图。我借用并修改了OMT(Object
Modeling Technique,对象建模技术)的图示法,以满足我的需要。本节将介绍用于类和对象图的图示法。
1.7.1 类图
类图用来说明类、类之间的静态关系和类的结构。在Objective-C中,应用程序可以定义协议、(抽象)类以及范畴 。
1. 协议、抽象类、具体类和范畴
通常,用圆角矩形框表示类实体,在上部用粗体标出名字,下部是操作的名字。如果你看的是本书的电子版,你会看到协议的标题栏的背景为粉色,而其他类实体的标题栏背景为浅蓝色。抽象的名字用斜体表示。因此,协议和抽象类用粗斜体表示。协议名用尖括号括起来。实例变量放在框的底部。各种类实体的例子如图1-2所示。
图1-2 左边为具有抽象操作的协议;中间为具有抽象操作和具体操作的抽象类;右边为具体类,带有具体操作、具体属性和实例变量
表示范畴有点儿麻烦,因为在本书写作时原来的OMT不支持范畴。范畴是对类的扩展,但又不是那个类的子类。所以要是用箭头来表示这种关系就会引起混乱。我想出了如图1-3所示的扩展类框图的图示法。
图1-3 左边为原来的类,右边为它的范畴扩展
原来的类框图在左边,有一个类似的矩形框附加到其上。范畴名用括号括起来。跟其他类相似,增加的操作放在框图的下部。这一图示法可能不是最灵活的,尤其是当设计中有100个范畴时,但用于本书的图示是足够了。
在类图或对象图中会有一些设计中的其他角色。这些角色可以是抽象实体(如客户端),或者设计范围之内或之外的其他类。灰色的圆角矩形框表示交互中的隐式角色,但对所讨论的问题来说并不重要。相反,参与者类会用黑实线的圆角矩形框来表示。如果这是电子书,参与者类的框图的背景色是浅蓝色的,隐式的类的背景色是透明或白色的(见图1-4)。
图1-4 左边为隐式类,右边为参与者类
2. 实例化
如果要表示一个类创建了另一个类,我会用带有箭头的虚线来表示这种关系。这被称为“创建”关系。箭头指向被实例化的类,如图1-5所示。
图1-5 一个类实例化另一个类
3. 继承
类继承的OMT图示法用空心三角形将子类连接到其父类。图1-6显示了这种关系,ConcreteClass是子类,代表继承的箭头指向其父类AbstractClass。对于接口继承(子类型化或符合接口),我用类似的箭头来表示这种关系,只是箭头后面的是虚线。图1-6也显示了这种关系。
图1-6 左边,具体类继承抽象类,体现了类继承的关系。右边,一个类子类型化
(符合)一个协议,体现了接口继承关系
4. 相识
我使用从一个类指向另一个类的箭头来表示相识(acquaintance)关系。这种关系与另一种叫做聚合的关系对于对象组合原则至关重要(聚合将在后面讨论)。图1-7显示了这种关系,ConcreteClass拥有对AnotherClass对象的引用,但不“拥有”AnotherClass对象的实体,而且引用也可以被其他对象分享。简单地说,ConcreteClass认识AnotherClass。
5. 聚合
跟相识关系一样,我使用箭头来表示对另一个对象的引用,只是在箭头的根部有一个菱形。但是这种引用关系有些不同。图1-8显示了ConcreteClass与AnotherClass有聚合(aggregation)关系。AnotherClass是ConcreteClass的一部分,ConcreteClass和AnotherClass构成聚合体。而聚合体由ConcreteClass来表示。AnotherClass不是聚合体。图中还显示了引用的另一种属性。我使用双头箭头来表示“多于一个”。因此,ConcreteClass包含有AnotherClass的多个实例,即instanceVariable_。
图1-7 ConcreteClass与AnotherClass形成相识关系
图1-8 ConcreteClass以对AnotherClass的多个引用形成聚合关系
6. 伪代码
有时候用伪代码简要记述某些操作的实现,可以更清楚地说明模式。伪代码注记的正文放在带卷角的矩形框中,如图1-9所示。
图1-9 伪代码注记
1.7.2 对象图
对象图只用来表示对象间的关系。它表示了设计模式中各个对象之间如何相互联系。对象名使用“aSomeClass”的格式,这里SomeClass是对象的类。表示对象的图形与类图中用到的很相似。对象被放在一个圆角矩形框中,矩形框有两部分,将对象名和它的对象引用分开。标题栏的背景也是浅蓝色。根部为圆形的实心箭头指向被引用的其他对象。图1-10是对象图的一个例子。
图1-10 用带有圆形根部的箭头表示源自aClass对象的引用的对象图
1.8 本书如何安排模式的讲解
本书涉及21种设计模式,根据其实际主题或应用领域分为以下8个功能部分:对象创建、接口适应、对象去耦合、抽象集合、行为扩展、算法封装、性能与对象访问,以及对象状态。
1.9 总结
本章介绍了设计模式的背景、历史和益处,以及影响应用程序架构设计的一些问题。我真的希望本章为掌握以下各章的真枪实弹作好了热身准备。

 

 

書城介紹  | 合作申請 | 索要書目  | 新手入門 | 聯絡方式  | 幫助中心 | 找書說明  | 送貨方式 | 付款方式 香港用户  | 台灣用户 | 大陸用户 | 海外用户
megBook.com.hk
Copyright © 2013 - 2024 (香港)大書城有限公司  All Rights Reserved.