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

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

你可能感兴趣的:(Design Patterns In Swift)