iOS 设计模式简介

36
iOS 设计模式简介

Transcript of iOS 设计模式简介

Page 1: iOS 设计模式简介

iOS 设计模式简介

Page 2: iOS 设计模式简介

• 设计模式的概念

• iOS中常见的设计模式

• 例子和使用场景

Page 3: iOS 设计模式简介

设计模式的概念

特定环境下的特定问题的解决方案

Page 4: iOS 设计模式简介

为何要用设计模式

• 更易于复用与扩展

• 更易于变更

• 优雅和高效

Page 5: iOS 设计模式简介

Cocoa框架中的设计模式

Cocoa 环境的很多架构和机制都有效地使用

了设计模式 :即为特定上下文中反复出现的

问题提供解决方案的抽象设计。

Page 6: iOS 设计模式简介

iOS中常见的设计模式

• MVC模型-视图-控制器( )

• 适配器o 协议( protocal)o 范畴( category)

• 观察者o 通告( Notification)o 键-值观察( KVO)

• 代理• 单例

Page 7: iOS 设计模式简介

模型-视图-控制器( MVC)

• 一个相当老的设计模式( Smalltalk早期)

• 高级别的模式,关注全局架构• 复合的模式(由几个更加基本的模式组成)• 面向对象的程序采用MVC的好处

o 对象更具重用性o 接口定义更加良好o 更加容易扩展o Cocoa中很多技术和架构都基于MVC,要求定制对象充当MVC定义的某种角色

Page 8: iOS 设计模式简介

MVC对象的作用和关系

• 模型(Model)负责包装数据和基本行为

• 视图( View)负责向用户表示信息

• 控制器( Controller)连接模型和视图

• 组合角色

Page 9: iOS 设计模式简介

Cocoa控制器对象的类型

• 仲裁控制器:o 通常是从 NSController类继承而来o Cocoa绑定技术中用到o 负责为 V和M之间的数据流提供仲裁或支持

• 协调控制器:o 通常是一个 NSWindowController或

NSDocumentController对象,或 NSObject定制子类的实例

o 检查(协调)整个或部分应用程序是否正常工作

Page 10: iOS 设计模式简介

复合的设计模式在原来的( Smalltalk)概念上,MVC是由合成( Composite)、策略( Strategy)和观察者( Observer)模式组成的。

• 合成模式: V是多个嵌套视图的集合• 策略模式:一个 C负责一或多个 V的策略• 观察者模式:M将状态变化通知其他感兴趣的对象(通常是 V)

Page 11: iOS 设计模式简介

传统版本的 MVC是一个复合设计模式

Page 12: iOS 设计模式简介

Cocoa版本的 MVC也是一种复合设计模式

Page 13: iOS 设计模式简介

MVC应用程序的设计原则

• 没有理由重新实现一个仲裁控制器• 在总体上最好的策略还是保持角色的分离• 尽可能多地使用 (至少在理论上 )可重用的对象

• 视图对象应该总是通过仲裁控制器对象来了解模型对象的变化

• 努力限制应用程序中类代码的依赖关系• 如果 Cocoa 提供的架构已经将 MVC 角色分配给具体类型的对象 ,则直接使用该架构

Page 14: iOS 设计模式简介
Page 15: iOS 设计模式简介

MVC交互示意图

Page 16: iOS 设计模式简介

Cocoa中的模型-视图-控制器

• 文档架构• 绑定技术• 应用程序的脚本能力• Core Data

• Undo

Page 17: iOS 设计模式简介

适配器

• 解决接口不兼容的问题• 把被适配者的行为传递到管道另一端的客户端

• 基本上有 2种方式o 类适配器

o 对象适配器

包装器模式

Page 18: iOS 设计模式简介

1. 类适配器

• 需要有定义了客户端要使用的一套行为的协议

• 用具体的适配器类来实现这个协议• 适配器类同时也要继承被适配者

Page 19: iOS 设计模式简介

2. 对象适配器

• 不继承被适配者,组合了一个对它的引用

Page 20: iOS 设计模式简介

类适配器 对象适配器

只针对单一的具体Adaptee类,把

Adaptee适配到Target

可以适配多个

Adptee及其子类

易于重载Adaptee的行为,因为是通过直接的子类化进行的适配

难以重载Adaptee的行为,需要借助于子类的对象而不是

Adaptee本身

只有一个Adapter对象,无需额外的指针间接访问

Adaptee

需要额外的指针以间接访问Adaptee并适配其行为

Page 21: iOS 设计模式简介

在 Cocoa框架中的应用

Page 22: iOS 设计模式简介

代理 / 委托 (delegation)

把类的接口变换为客户端要求的另一种接口

Cocoa Touch 框架中的类

委托协议程序中的其他类

Page 23: iOS 设计模式简介

块 (block)

• 几乎可以在任何地方进行块的定义,然后让接收器在以后使用它

• 不影响所涉及类的任何继承• 跟协议与类相比,使代码和结构更加简洁• 取代回调• 许多流行的开源库使用 block来取代代理方法

闭包 (closure)

Page 24: iOS 设计模式简介
Page 25: iOS 设计模式简介

观察者

描述:

• 定义了一种一对多的依赖关系

• 当一个对象的状态发生改变时,所有依赖于

它的对象都得到通知并被自动更新

发布 /订阅模式

Page 26: iOS 设计模式简介
Page 27: iOS 设计模式简介

什么时候使用

• 主题的改变需要让所有有关的对象知道,但

是不知道这些对象的数量和具体类型

• 改变发生在同一个对象中,并在别的地方需

要将相关状态进行更新

Page 28: iOS 设计模式简介

实现方法

1. Notification

2. KVO( Key-Value Observing)

3.标准方法

Page 29: iOS 设计模式简介

1. Notification

• 使用了操作系统的功能

• 对象间可以不认识

• Cocoa Touch 框架提供了一些类,开发者不

必写自己的类

// 推送通知[[NSNotificationCenter defaultCenter] postNotificationName:@"login" object:nil];

// 添加观察者接收通知[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(loadUserID) name:@"login" object:nil];

Page 30: iOS 设计模式简介

2. KVO (Key-Value Observing)

• 某个对象中的特定属性发生了改变,别的对象可以获得通知

• Cocoa框架功能,基于 KVC (Key-value

coding)

• KVO/KVC 实现机理分析

// 注册-(void)addObserver:(NSObject *)anObserver forKeyPath:(NSString *)keyPath options:(NSKeyValueObservingOptions)options context:(void*)context

// 实现响应-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context

Page 31: iOS 设计模式简介

3. 标准方法

• 主题知道所有的观察者,但是不知道它们的类型

• 自己创建 Subject 和 Observer 的协议

Page 32: iOS 设计模式简介

单例

描述:

• 一个类只有一个实例对象

• 提供一个全局的入口点对这个实例对象进行

访问

Page 33: iOS 设计模式简介

何时使用

• 类只能有一个实例,且必须从一个熟悉的访问点对其进行访问

• 这个唯一的实例只能通过子类化进行扩展,而且扩展的对象不会破坏客户端代码

Page 34: iOS 设计模式简介

实现

• iOS SDK 中许多类使用了单例,如

UIApplication, NSUserDefaults,

NSNotificationCenter...

• 『趣读』和『 Iamhere』的网络通信方法

程序启动的时候,会调用 UIApplicationMain方法,实例化一个 UIApplication对象。之后在程序中的任意地方调用 sharedApplication方法都将返回一个与当前应用程序相关的 UIApplication实例( UIApplicationMain方法中创建的 UIApplication单例)

+ (AFIHClient *)sharedClient:(NSString *)path{ static AFIHClient *_sharedClient = nil; static dispatch_once_t onceToken; // 进程锁 dispatch_once(&onceToken, ^{ // 最多调用一次 _sharedClient = [[AFIHClient alloc] // 第一次会调用 init initWithBaseURL:[NSURL URLWithString:KAFUrl]]; }); ... .... return _sharedClient;}

Page 35: iOS 设计模式简介

例子和应用场景

Page 36: iOS 设计模式简介

问题