学计算机的那个

不是我觉到、悟到,你给不了我,给了也拿不住;只有我觉到、悟到,才有可能做到,能做到的才是我的.

0%

【读书笔记】Objective-C编程之道:iOS设计模式解析 上

iOS应用程序的基础框架Cocoa Touch框架内容丰富、结构优美,通过将各种设计模式应用到其基础结构中,为第三方开发者提供了很好的可扩展性和灵活性。因此,要充分利用这一框架,应当深刻理解
并恰当应用设计模式。本书受到GoF的经典著作《设计模式》的启发,旨在引导大家掌握如何在iOS平台上以Objective-C语言实现Cocoa Touch开发所要用到的传统设计模式。

设计模式初体验

你好,设计模式

设计模式是有用的抽象化工具,用于解决工程和建筑等其他领域的设计问题。在软件领域,设计模式是为特定场景下的问题而定制的解决方案。

通过给程序的变动部分定义接口而对其封装和隔离,这些部分的变动就独立于程序的其他部分,因为他们不依赖于任何细节。以后就可以变更或扩展这些可变的部分而不影响程序的其他部分。

MVC

  1. 在模型对象中封装数据和基本行为
    理想状况下,模型对象同用于对其进行显示和编辑的用户界面之间不应有任何直接的关联。
  2. 使用视图对象向用户展示信息
    视图对象通常从应用程序的模型数据获取数据用以展示,它可以跟一个模型对象的部分、整体或者多个模型对象合作。
  3. 用控制器对象联系起模型和视图
    控制器对象就像视图对象和模型对象的中间人。它建立起沟通渠道,使视图得以知晓模型的变更而给予响应。

MVC本身并不是最基本的设计模式,它包含了若干更加基本的设计模式。Cocoa Touch的MVC用到的设计模式有:组合、命令、中介者、策略、观察者。

组合:视图对象之间的协作方式构成一个视图层次体系。其中既可以有复合视图(UITableView),也可以有独立视图(UITextFIeld和UIButton)。每个层次的每个视图节点都可以响应用户的操作并把自己绘制到屏幕上。

命令:这是一种“目标-动作”机制,视图对象可以延迟其他对象(比如控制器)的执行,让其他对象等到发生了某些事件后再执行。

中介者: 控制器对象起着中间人的作用。它构成了在模型和视图对象之间传递数据的双向通道。

策略: 控制器可以是视图对象的一个“策略”。视图对象将自身隔离,以期维持其作为数据展示器的唯一职责,而将一切应用程序特有的界面行为的决定委派给它的“策略”对象。

观察者:模型对象向它所关注的控制器对象发出内部状态变化的通知。

设计原则

针对接口编程,而不是针对实现编程

  • 类继承与接口继承(子类型化)的区别在哪里?

接口定义了类型,接口继承(子类型化)让我们可以用一个对象代替另一个对象。

类继承是通过复用父类的功能或者只是简单地共享代码和表述,来定义对象的实现和类型的一种机制。

区别在于一个对象可以具有多种类型而不同类的对象可以有相同的类型

子类型的所有对象,都可以针对协议或抽象类的接口的请求作出应答。

  • 使用协议还是抽象基类?
    协议(@protocol)并不定义任何实现,而只声明方法,以确定符合协议的类的行为。因此协议是只定义了抽象行为的“接口”

抽象基类(Abstract Base Class) 通过抽象基类,我们可以生成一些其他子类可以共享的默认行为。

抽象基类与通常的类相似,只是预留了一些可以或应该由子类重载的行为

变更过去定义的协议可能会破坏实现该协议的类,协议是抽象类型与具体类型之间的一种合约,如果变更合约,所有相关的事项也需要变更。唯一例外是,只使用@optional指定将协议的部分方法变为“可选的”

抽象基类在接口变更方面要稍微灵活一些。可以向抽象基类随意追加新的方法,而不会破坏继承链的其他部分。而且,对于子类可能用到的占位方法中定义的默认行为,可以随意地进行追加、删除或分解。

只对一个抽象类型进行子类化的类,可以让它们直接对抽象类型进行子类化。若是以后更改设计,以使抽象类型也能够是UIView等的子类,通常的灵活做法是,首先为不需要子类化其他类的类定义一个抽象基类,然后可以定义一个同名协议,让包括这个抽象基类在内的其他类去实现。例如NSObject基类符合NSObject协议。

对象组合与类继承
子类化常常被称为白箱复用,因为父类的内部描述与细节通常对子类可见
对象组合要求被组合的对象具有定义良好的接口,并且通过从其他对象得到的引用在运行时动态定义。所以可以将对象组合到其他对象中,以构建更加复杂的功能。由于对象的内部细节对其他对象不可见,这种类型的复用称为黑箱复用。

对象创建

原型

在许多面向对象的应用程序中,有些对象的创建代价过大或过于复杂,要是可以重建相同的对象并作轻微的改动,事情会容易很多。应用于“复制”操作的模式称为原型(Protorype)模式。复制(cloning)指用同一模具生产一系列的产品。

指针只是存储内存中资源地址的占位符

  • Cocoa Touch框架中对象复制
    框架为NSObject的派生类提供了实现深复制的协议,NSObject的子类需要实现NSCopying协议及其方法(id)copywithZone:(NSZone*)zone

工厂方法

工厂方法也称为虚构造器。它适用于这种情况:一个类无法预期需要生成哪个类的对象,想让其子类来指定所生成的对象。

  • Cocoa Touch 框架中应用工厂方法
    [[SomeClass alloc]init].NSNumber有很多numberWith*方法:numberWithBool:和numberWithChar:

抽象工厂

抽象工厂提供一个固定的接口,用于创建一系列有关联或相依存的对象,而不必指定其具体类或其创建的细节。

软件设计的黄金法则:变动需要抽象

  • Cocoa Touch框架中使用抽象工厂
    创建Cocoa Touch对象有两种方式,使用allloc再init的方法,或者使用类中的+className…方法。
1
2
3
NSNumber* boolNumber = [NSNumber numberWithBool:YES];
NSNUmber* charNumber=[NSNumber numberWithChar:'a'];
'''

接受不同类型的参数并返回NSNumber实例的类方法是类工厂方法

类簇是基础框架中一种常见的设计模式,基于抽象工厂模式的思想。将若干相关的私有具体工厂子类集合到一个公有的抽象超类之下。类簇是抽象工厂的一种形式。比如NSNumber本身是一个高度抽象的工厂,而NSCFBollean和NSCFNumber是具体的工厂子类。

其它实现为类簇的基础类有NSData、NSArray、NSDictionary、NSString

生成器

有时构建某些对象有多种不同方式,如果这些逻辑包含在构建这些对象的类的单一方法中,其构建的逻辑会非常混乱(针对各种构建需要一大片嵌套if-else或者swifth-case)。如果能够把构建过程分解为客户-指导者-生成器的关系,那么过程将更容易管理与复用。

生成器模式能够帮助构建涉及部件与表现的各种组合的对象。

单例

singleton定义为“有且仅有一个元素的集合”

单例类总是返回自己的同一个实例,它提供了对类的对象所提供的资源的全局访问点。

  • 在Cocoa Touch框架中使用单例模式
    UIApplication、UIAccelerometer、NSFileManager

接口适配

适配器

适配器模式,用于连接两种不同种类的对象,使其毫无问题地协同工作。(把类的接口变换为客户端要求的另一种接口)

  • 两种实现适配器的方式

第一种是通过继承来适配两个接口,称为类适配器。(c++中类适配器是通过多重继承实现的,Objectivve-C中,类可以实现协议,同时又继承超类,达到C++的多重继承的效果)

第二种方式称为对象适配器,对象适配器不继承被适配者,而是组合了一个对它的引用。

  • 在Cocoa Touch框架中使用委托模式
    Delegate是Cocoa Touch框架所采用的委托模式的一种形式,这里的客户端是Cocoa Touch框架中的类,Target是委托协议,实现协议的类会是个适配器,应用程序中的其它类是与框架不匹配而需要适配的类。

桥接

桥接模式的目的是把抽象层次结构从其实现中分离出来,使其能够独立变更。抽象层定义了供客户端使用的上层的抽象接口,实现层定义了供抽象层次使用的底层接口。实现类的引用被封装于抽象层的实例中时,桥接就形成了。

外观

为系统中的一组接口提供一个统一的接口,外观定一个一个高层接口,让子系统更易于使用

对象去耦

中介者

用一个对象来封装一系列对象的交互方式。中介者使各对象不需要显示地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。

中介者模式以中介者内部的复杂性代替交互的复杂性,因为中介者封装与合并了客户端的各种协作逻辑,自身可能变得比它们任何一个都复杂,这会让中介者本身成为无所不知的庞然大物,并且难以维护,此时,可以考虑使用另一种设计模式把它分解,要创造性的混用和组合设计模式解决同一个问题,每个设计模式就像一个乐高积木块,整个应用程序可能要使用彼此配合的各种“积木块”来建造。

观察者

观察者模式也叫做发布-订阅模式。定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都能得到通知并被自动更新。

  • Cocoa Touch中使用观察者模式
  1. 通知NSNotificationCenter
  2. 健-值观察KVO(基于NSKeyValueObserving非正式协议)

参考

  1. Objective-C 编程之道:iOS设计模式解析