Design Patterns In Swift

  • 详解Swift中的iOS设计模式-开篇
  • 详解Swift中的iOS设计模式-MVC
  • 详解Swift中的iOS设计模式-单例模式
  • 详解Swift中的iOS设计模式-外观模式
  • 详解Swift中的iOS设计模式-装饰者模式
  • 详解Swift中的iOS设计模式-适配器模式
  • 详解Swift中的iOS设计模式-观察者模式
  • 详解Swift中的iOS设计模式-备忘录模式

翻译自 Introducing iOS Design Patterns in Swift – Part 1/2 ,本教程 objc 版本的作者是 Eli Ganem ,由 Vincent Ngo 更新为 Swift 版本。

Introducing iOS Design Patterns in Swift – Part 1/2
Introducing iOS Design Patterns in Swift – Part 2/2
Intermediate Design Patterns in Swift
Design-Patterns-In-Swift

iOS 设计模式

说到设计模式,相信大家都不陌生,但是又有多少人知道它背后的真正含义?绝大多数程序员都知道设计模式十分重要,不过关于这个话题的文章却不是很多,开发者们在开发的时候有时也不太在意设计模式方面的内容。

设计模式针对软件设计中的常见问题,提供了一些可复用的解决方案,开发者可以通过这些模板写出易于理解且能够复用的代码。正确的使用设计模式可以降低代码之间的耦合度,从而很轻松的修改或者替换以前的代码。

如果你对设计模式还很陌生,那么告诉你一个好消息!在 iOS 的开发过程中,其实你不知不觉已经用了很多设计模式。这得益于 Cocoa 提供的框架和一些良好的编程习惯。接下来的这篇教程将会带你一起飞,去领略设计模式的魅力。

整个教程分为两篇文章,通过整个系列的学习,我们将会完成一个完整的应用,展示音乐专辑和专辑的相关信息。

通过这个应用,我们会接触一些 Cocoa 中常见的设计模式:

  • 创建型 (Creational):单例模式 (Singleton)
  • 结构型 (Structural):MVC、装饰者模式 (Decorator)、适配器模式 (Adapter)、外观模式 (Facade)
  • 行为型 (Behavioral):观察者模式 (Observer)、备忘录模式 (Memento)
    嘿嘿嘿别愁眉苦脸的嘛,这篇文章不是什么长篇大论的理论知识,你会在开发应用的过程中慢慢学会这些设计模式。

其实当你创建一个新的 Xcode 的项目的时候,你的代码里就已经有很多设计模式的影子了: MVC、委托、代理、单例 - 真是众里寻他千百度,得来全不费功夫。

MVC - 设计模式之王

Model-View-Controller (缩写 MVC ) 是 Cocoa 框架的一部分,并且毋庸置疑是最常用的设计模式之一。它可以帮你把对象根据职责进行划分和归类。

作为划分依据的三个基本职责是:

  • 模型层 (Model) :存储数据并且定义如何操作这些数据。
  • 视图层 (View) :负责模型层的可视化展示,并且负责用户的交互,一般来说都是继承自 UIView 这个基类。
  • 控制器 (Controller) :控制器是整个系统的掌控者,它连接了模型层和数据层,并且把数据在视图层展示出来,监听各种事件,负责数据的各种操作。
    如果你的项目遵循 MVC 的设计模式,那么各种对象要不是 Model ,要不是 View ,要不就是 Controller。当然在实际的开发中也可以灵活变化,比如结合具体业务使用 MVVM 结构给 ViewController 瘦瘦身,也是可以的。
    三者之间的关系如下:


模型层通知控制器层任何数据的变化,然后控制器层会刷新视图层中的数据。视图层可以通知控制器层用户的交互事件,然后控制器会处理各种事件以及刷新数据。

你可能会感觉奇怪:为什么要把这三个东西分开来,而不能揉在一个类里呢?那样似乎更简单一点嘛。

Naive.

之所以这样做,是为了将代码更好的分离和重用。理想状态下,视图层应当和模型层完全分离。如果视图层不依赖任何模型层的具体实现,那么就可以很容易的被其他模型复用,用来展示不同的数据。

举个例子,比如在未来我们需要添加电影或者什么书籍,我们依旧可以使用 AlbumView 这个类作为展示。更久远点来说,在以后如果你创建了一个新的项目并且需要用到和专辑相关的内容,你可以直接复用 Album 类因为它并不依赖于任何视图模块。这就是 MVC 的强大之处,三大元素,各司其职,减少依赖。

单例模式

单例模式确保每个指定的类只存在一个实例对象,并且可以全局访问那个实例。一般情况下会使用延时加载的策略,只在第一次需要使用的时候初始化。

注意:在 iOS 中单例模式很常见,
NSUserDefaults.standardUserDefaults() 、
UIApplication.sharedApplication() 、
UIScreen.mainScreen() 、
NSFileManager.defaultManager() 这些都是单例模式。

你可能会疑惑了:如果多于一个实例又会怎么样呢?代码和内存还没精贵到这个地步吧?

某些场景下,保持实例对象仅有一份是很有意义的。举个例子,你的应用实例 (UIApplication),应该只有一个吧,显然是指你的当前应用。还有一个例子:设备的屏幕 (UIScreen) 实例也是这样,所以对于这些类的情况,你只想要一个实例对象。

单例模式的应用还有另一种情况:你需要一个全局类来处理配置文件。我们很容易通过单例模式实现线程安全的实例访问,而如果有多个类可以同时访问配置文件,那可就复杂多了。

外观模式

外观模式在复杂的业务系统上提供了简单的接口。如果直接把业务的所有接口直接暴露给使用者,使用者需要单独面对这一大堆复杂的接口,学习成本很高,而且存在误用的隐患。如果使用外观模式,我们只要暴露必要的 API 就可以了。

下图演示了外观模式的基本概念:



API 的使用者完全不知道这内部的业务逻辑有多么复杂。当我们有大量的类并且它们使用起来很复杂而且也很难理解的时候,外观模式是一个十分理想的选择。

外观模式把使用和背后的实现逻辑成功解耦,同时也降低了外部代码对内部工作的依赖程度。如果底层的类发生了改变,外观的接口并不需要做修改。

举个例子,如果有一天你想换掉所有的后台服务,你只需要修改 API 内部的代码,外部调用 API 的代码并不会有改动。

装饰者模式

装饰者模式可以动态的给指定的类添加一些行为和职责,而不用对原代码进行任何修改。当你需要使用子类的时候,不妨考虑一下装饰者模式,可以在原始类上面封装一层。

在 Swift 里,有两种方式实现装饰者模式:扩展 (Extension) 和委托 (Delegation)。

扩展

扩展是一种十分强大的机制,可以让你在不用继承的情况下,给已存在的类、结构体或者枚举类添加一些新的功能。最重要的一点是,你可以在你没有访问权限的情况下扩展已有类。这意味着你甚至可以扩展 Cocoa 的类,比如 UIView 或者 UIImage 。

举个例子,在编译时新加的方法可以像扩展类的正常方法一样执行。这和装饰器模式有点不同,因为扩展不会持有扩展类的对象。

注意:类是可以重写父类方法的,但是在扩展里不可以。扩展里的方法和属性不能和原始类里的方法和属性冲突。

委托

装饰者模式的另一种实现方案是委托。在这种机制下,一个对象可以和另一个对象相关联。比如你在用 UITableView ,你必须实现 tableView(_:numberOfRowsInSection:) 这个委托方法。

你不应该指望 UITableView 知道你有多少数据,这是个应用层该解决的问题。所以,数据相关的计算应该通过 UITableView 的委托来解决。这样可以让 UITableView 和数据层分别独立。视图层就负责显示数据,你递过来什么我就显示什么。

UITableView 的工作仅仅是展示数据,但是最终它需要知道自己要展示那些数据,这时就可以向它的委托询问。在 objc 的委托模式里,一个类可以通过协议来声明可选或者必须的方法。

看起来似乎继承然后重写必须的方法来的更简单一点。但是考虑一下这个问题:继承的结果必定是一个独立的类,如果你想让某个对象成为多个对象的委托,那么子类这招就行不通了。

注意:委托模式十分重要,苹果在 UIKit 中大量使用了该模式,基本上随处可见。

适配器模式 - Adapter

适配器把自己封装起来然后暴露统一的接口给其他类,这样即使其他类的接口各不相同,也能相安无事,一起工作。

如果你熟悉适配器模式,那么你会发现苹果在实现适配器模式的方式稍有不同:苹果通过委托实现了适配器模式。委托相信大家都不陌生。举个例子,如果一个类遵循了 NSCoying 的协议,那么它一定要实现 copy 方法。

观察者模式 - Observer

在观察者模式里,一个对象在状态变化的时候会通知另一个对象。参与者并不需要知道其他对象的具体是干什么的 - 这是一种降低耦合度的设计。这个设计模式常用于在某个属性改变的时候通知关注该属性的对象。

常见的使用方法是观察者注册监听,然后再状态改变的时候,所有观察者们都会收到通知。

在 MVC 里,观察者模式意味着需要允许 Model 对象和 View 对象进行交流,而不能有直接的关联。

Cocoa 使用两种方式实现了观察者模式: Notification 和 Key-Value Observing (KVO)。

备忘录模式 - Memento

备忘录模式捕捉并且具象化一个对象的内在状态。换句话说,它把你的对象存在了某个地方,然后在以后的某个时间再把它恢复出来,而不会打破它本身的封装性,私有数据依旧是私有数据。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,132评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,802评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,566评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,858评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,867评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,695评论 1 282
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,064评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,705评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,915评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,677评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,796评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,432评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,041评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,992评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,223评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,185评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,535评论 2 343

推荐阅读更多精彩内容

  • 发现 关注 消息 iOS 第三方库、插件、知名博客总结 作者大灰狼的小绵羊哥哥关注 2017.06.26 09:4...
    肇东周阅读 12,019评论 4 62
  • 今天写什么呢?今天写什么呢?其实已不重要,想写什么就写什么,这才来得肆意,刻意去想,多累!半月已过,从担心到从容,...
    易水寒一x阅读 182评论 0 0
  • 我们中的多数从小就被灌输了一种思想:稳妥才是人生最终的主题。你说你想创业,周围人会劝你太冒险还是算了,找个踏实的工...
    爱吃芒果的猫头鹰阅读 199评论 0 0
  • 笔下人物的血肉有三分是自己的灵魂,剩下的七分是对生活的调侃,有人笔下画江湖,有人梦中执剑走天涯。 希望你在自己的江...
    遗忘的一隅阅读 667评论 0 3