ios 设计模式总结
设计模式:
备注:消息传递模型(Message Passing)是Objective-C语言的核心机制。在Objective-C中,没有方法调用这种说法,只有消息传递。在C++或Java中调用某个类的方法,在Objective-C中是给该类发送一个消息。在C++或Java里,类与类的行为方法之间的关系非常紧密,一个方法必定属于一个类,且于编译时就已经绑定在一起,所以你不可能调用一个类里没有的方法。而在Objective-C中就比较简单了,类和消息之间是松耦合的,方法调用只是向某个类发送一个消息,该类可以在运行时再确定怎么处理接受到的消息。也就是说,一个类不保证一定会响应接收到的消息,如果收到了一个无法处理的消息,那么程序就是简单报一个错。甚至你可以向一个值为nil的空对象发送消息,系统都不会出错或宕掉。这种设计本身也比较符合软件的隐喻。
原型模式:
只要复制自身要比手工实例化对象要好,都可以使用原型对象。此模式的最低限度是生成对象的真实副本(即深度复制)。
Cocoa Touch框架为NSOBject的派生类提供了实现深度复制的协议。NSObject的子类需要实现NSCopying协议及其方法:-(id)copyWithZone:(NSZone *)zone。 NSObject有一个实例方法叫做(id)copy。 默认的copy方法调用[self copyWithZone:nil] 。对于采纳了NSCopying协议得子类,需要实现这个方法。
工厂方法:
工厂方法适用情形:
1, 编译时无法预期要创建的对象的类
2, 类想让其子类决定在运行时创建什么
3, 类有若干子类,而你想将返回哪个子类这一信息局部化。
使用这一模式的常见例子是ccoca touch框架中的NSNumber。
NSNumber可以将基本数据类型包装起来,形成一个对象,这样就可以给其发送消息,装入NSArray中等等。
NSNumber * intNumber=[NSNumber numberWithInt:100];
NSNumber *floatNumber=[NSNUmber numberWithFloat:100.00];
int i=[intNumber intValue];
if([intNumber isEqualToNumber:floatNumber]) ....
NSNumber继承NSObject ,可以使用比较 compare: isEqual等消息
numberWithX是工厂方法。
抽象工厂:
抽象工厂常见于cocoa touch框架。有很多基础类采用这一模式。NSNumber就是一个抽象工厂。
生成器模式:
生成器模式把过程分为客户—指导者—生成器(client-director-buider)的关系。
何时使用生成器模式:
1. 需要创建涉及各种部件的复杂对象
2. 创建过程需要一不同方式构建对象
例子:创建游戏中的角色。ChasingGame(指导者) CharacterBuilder(基类 生成器)
stardCharacterBuilder(子类生成器) character(角色类)
单例模式:
这一模式的意图是使得类的一个对象成为系统中唯一的实例。
使用单例模式的情况:
1. 类只能有一个实例,而且必须从一个为人熟知的访问点对其进行访问,比如工厂方法。
2. 这个唯一的实例只能通过子类化对其进行扩展,且扩展的对象不会破坏客户端代码
框架中极为常见的一个单例类是UIApplicaton类。每一个应用程序有且仅有一个UIApplication的实例。他由UIApplicationMain函数在应用程序启动时创建为单例对象。之后,对同一UIApplication实例可以通过其sharedApplication类方法进行访问。
还有UIAccelermeter类和NSFileManager类也是单例类。
适配器模式:
适配器也称包装器(wrapper)。适配器模式用于连接两种不同种类的对象,使其毫无问题地协同工作。
基本上有两种实现适配器的方式。第一种是通过继承来适配两个接口。这种称为类适配器。
如obj-c中的继承并实现协议。
还有一种方式称为对象适配器,与类适配不同,对象适配不继承被适配者,而是组合了一个对他的引用。
适配器模式适用情形:
1. 已有类的接口与需求不匹配。
2. 想要一个可复用的类
3. 需要适配一个类的几个子类
Obj-c中的委托就是对适配器模式的运用
桥接模式:
桥接模式的目的是把抽象层次结构从具体实现中分离。见(p105)
外观模式:
外观模式位子系统中的一组不同接口提供统一接口。为子系统的接口提供简化的接口。
外观模式的适用情形:
1. 子系统正变得复杂。子系统用起来较困难。
2. 可以使用外观对子系统进行分层。 (p115)
中介者模式:
中介者模式用于定义一个集中地场所,对象间的交互可以在一个中介者对象中处理。其他对象不必彼此交互,因此减少了他们的依存关系。
何时使用中介者模式:
1. 对象间的交互虽定义明确然而非常复杂,导致对象彼此相互依赖难以理解
2. 因为对象引用许多其他对象并与其通讯,导致对象难以复用。
3. 想要定制一个分布在多了类中的逻辑或行为,又不想生成太多子类
如ios项目中涉及很多的试图迁移,可以创建一个专门的类来管理这些迁移,这个类就是个中介者。
观察者:
观察者模式又称发布—订阅模式。观察者(订阅杂志的人)通过通知器(杂志发行商)把自己注册到(订阅)特定的通知(杂志)。当有通知的时候,观察者只通过通知器得到他订阅的通知。
观察者模式适用情形:
1. 有两种抽象类型相互依赖。将他们封装在各自的对象中,就可以对他们进行单独改变和复用。
2. 对一个对象的改变需要同时改变其他对象,而不知道具体有多少对象有待改变
3. 一个对象必须通知其他对象,而他又不知道其他对象是什么。
Cocoa touch框架用两种技术改写了观察者模式。通知和健值观察。(具体见p139)
组合模式:
组合模式可以让我们把相同基类型的对象组合到树状结构中。其中的父节点包含同类型的子节点。
组合模式适用情形:
1. 想获得对象的抽象的树形表示
2. 想让客户端同一处理组合结构中的所有对象
在cocoa touch框架中,UIView被组织成一个组合结构。每一个UIView实例可以包含UView的其他实例,形成统一的树形结构。
迭代器模式:
迭代器提供了一种顺序访问聚合(集合)对象中元素的方法,而无需暴露结构的底层表示和细节。
迭代器模式适用情形:
1. 需要访问组合对象中的内容
2. 需要通过多种方式遍历组合对象
3. 需要提供一个统一接口,用来遍历各种类型的组合对象
苹果公司用枚举器/枚举改写了迭代器模式。基础框架中的类NSEnmerator类实现了迭代器模式。抽象的NSEnmerator类的私有具体子类返回枚举器对象。能够顺序遍历各种组合,数组,set,字典。
访问者模式:
访问者模式可以用日常生活中的例子描述。例如管道工来你家修管子。管道工就是访问者。你开门让他进来(接受访问),然后他进来修管子(访问)。访问者模式的构造方法见(p181)
访问者模式适用情形:
1. 一个复杂的对象结构包含很多其他对象,他们有不同的接口,但是想对这些对象实施一些依赖与其他具体类型的操作。
2. 需要对一个组合结构中的对象进行很多不想关的操作,但是不想让这些操作污染这些对象的类。
3. 定义结构复杂的类很少做修改,但经常需要向其添加新的操作
访问者模式的功效类似于obj-c里的category很象。访问者模式是扩展组合结构的一种强大的方式。
装饰模式:
装饰模式的目的是向对象添加行为,而不破坏其原有风格,因此增强的对象是同一个累的加强版。可以使用子类或category来实现模式。装饰模式类图见(p191)
装饰模式的使用情形:
1. 想要在不影响其他对象的情况下,以动态,透明的方式给单个对象添加职责。
2. 想要扩展一个类的行为,却做不到。
3. 对类的职责的扩展是可选的
责任链模式:
责任链模式的主要思想是,对象引用了同一类型的对象,形成了一条链,链中每个对象实现了同样的方法,处理对链中第一个对象发起的同一请求。如果一个对象不知道如何处理请求,他就把请求传给下一个响应器(successor)
责任链适用情形:
1. 有多个对象可以处理请求,而处理程序只有在运行时才能确定
2. 向一组对象发出请求,而不想显示指定处理请求的特定程序。
RPG游戏中的防御系统就可以用责任链模式
模板方法模式:
模板方法定义一个操作中算法的骨架,而将一些步骤延迟到子类中。
模板方法的适用情形:
1. 需要一次性实现算法的可变部分,并将可变的行为留给子类来实现
2. 子类的共同行为被提取到公共类中,一避免代码重复。
3. 需要控制子类的扩展。
在框架设计中,模板方法非常常见。模板方法是代码复用的基本技术。Cocoa touch中的模板方法有UIView中的-(void)drawRect(CGRect) rect
rotatingHeaderView等方法(p229)
策略模式:
面向对象的设计中,我们可以把算法分离为不同的类,称为策略。策略模式中一个关键角色是策略类它为所有支持的相关算法声明了一个共同接口。另外,还有使用策略接口来实现相关算法的具体策略类。
何时使用策略模式:
1. 一个类在其操作中使用多个条件语句来定义许多行为。
2. 需要算法的各种变体
3. 需要避免把复杂的,与算法相关的数据结构暴露给客户端(见p230)
命令模式:
面向对象设计中,我们借用了类似思想,把指令封装在各种命令对象中。命令对象可以被传递并且在指定的时刻被不同的客户端复用(p241)
何时使用命令模式:
1. 想让应用程序支持撤销与恢复
2. 想要在不同时刻对请求执行指定,排列和操作
3. 想要记录修改日志。
NSInvocationa NSUndoManager和“目标动作”机制是cocoa touch框架中对这个模式的典型应用。
享元模式:
在面向对象软件设计中,利用公共对象不仅能节省资源还能提高性能。比方说,某个任务需要一个类的一百万个实例,但我们可以把这个类的实例让大家共享,而把某些独特的信息放在外部,节省资源。实现享元模式需要两个关键组件。通常是可共享的享元对象和保存他们的共享池。
何时使用享元模式:
1. 应用程序使用很多对象
2. 在内存中保存对象会影响内存性能
百花池例子很好地演示了享元模式(p262)
代理模式:
利用代理模式,把操作推迟给代理对象处理来提升性能并提供对象访问。
有以下几种代理模式。
远程代理,虚拟代理,保护代理,智能引用代理。
何时使用代理模式:
1. 需要一个远程代理,为位于不同的地址空间或网络中的对象提供本地代表。
2. 需要一个虚拟代理,来根据要求创建重型的对象
3. 需要以一个保护代理,来根据不同访问权限控制对原对象的访问
4. 需要一个智能引用代理通过对实体对象的引用进行计数来管理内存。
ios应用中代理模式的一个常见例子是邮件应用(p278)
无论在何种ios设备中总是推荐lazy loading。 Lazy loading就是利用代理模式实现
备忘录模式:
在不破坏封装的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,这样以后就可以恢复这个对象的状态。这个模式有三个关键角色:原发器(originator),备忘录(mementor)和看管人。其思想很简单。原发器创建一个包含其状态的备忘录,并传给看管人,看管人不知如何与备忘录进行交互,但会把备忘录放在安全之处保管好。
何时使用备忘录模式:
1. 需要保存一个对象在某个时刻的状态
2. 用于获取状态的接口会暴露实现细节,需要将其隐藏起来
Cocoa Touch框架在归档,属性列表序列化和核心数据中才用了备忘录模式。
ios 设计模式总结的更多相关文章
- IOS设计模式之一(MVC模式,单例模式)
iOS 设计模式-你可能已经听说过这个词,但是你真正理解它意味着什么吗?虽然大多数的开发者可能都会认为设计模式是非常重要的,然而关于设计模式这一主题的文章却不多,并且有时候我们开发者在写代码的时候也不 ...
- iOS 设计模式之工厂模式
iOS 设计模式之工厂模式 分类: 设计模式2014-02-10 18:05 11020人阅读 评论(2) 收藏 举报 ios设计模式 工厂模式我的理解是:他就是为了创建对象的 创建对象的时候,我们一 ...
- iOS设计模式之生成器
iOS设计模式之生成器 1.生成器模式的定义 (1): 将一个复杂的对象的构件与它的表示分离,使得相同的构建过程能够创建不同的表示 (2): 生成器模式除了客户之外还包括一个Director(指导者) ...
- IOS设计模式之三:MVC模式
IOS设计模式之三:MVC模式 模型-视图-控制器 这个模式其实应该叫做MCV,用控制器把model与view隔开才对,也就是model与view互相不知道对方的存在,没有任何瓜葛,他们就像一个团 ...
- iOS设计模式 - 享元
iOS设计模式 - 享元 原理图 说明 享元模式使用共享物件,用来尽可能减少内存使用量以及分享资讯给尽可能多的相似物件:它适合用于只是因重复而导致使用无法令人接受的大量内存的大量物件.通常物件中的部分 ...
- iOS设计模式 - 责任链
iOS设计模式 - 责任链 原理图 说明 在责任链模式里,很多对象由每一个对象对其下家的引用而连接起来形成一条链.请求在这个链上传递,直到链上的某一个对象决定处理此请求.发出这个请求的客户端并不知道链 ...
- iOS设计模式 - 模板
iOS设计模式 - 模板 原理图 说明 定义一个操作中的算法的骨架,而将步骤延迟到子类中.模板方法使得子类可以不改变一个算法的结构即可重定义算法的某些特定步骤. 源码 https://github.c ...
- iOS设计模式 - 访问者
iOS设计模式 - 访问者 原理图 说明 表示一个作用于某对象结构中的各元素的操作,它使你可以在不改变各元素类的前提下定义作用于这些元素的新操作. 1.Visitor 抽象访问者角色,为该对象结构中具 ...
- iOS设计模式 - 迭代器
iOS设计模式 - 迭代器 原理图 说明 提供一种方法顺序访问一个聚合对象中的各种元素,而又不暴露该对象的内部表示. 源码 https://github.com/YouXianMing/iOS-Des ...
- iOS设计模式 - 中介者
iOS设计模式 - 中介者 原理图 说明 用一个中介对象来封装一系列的对象交互.中介者使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互. 注:中介者对象本身没有复用价值 ...
随机推荐
- [Xcode 实际操作]六、媒体与动画-(14)使用SystemSoundId播放简短声音
目录:[Swift]Xcode实际操作 本文将演示如何播放音频素材. 在项目名称上点击鼠标右键,弹出右键菜单, 选择[Add Files to "DemoApp"],往项目中导入文 ...
- VUE之环境安装
一.环境安装 软件安装: nodejs https://nodejs.org/en/ vscode https://code.visualstudio.com/docs/?dv=win python- ...
- C 语言实例 - 判断正数/负数
C 语言实例 - 判断正数/负数 用户输入一个数字,判断该数字是正数还是负数或是零. 实例 #include <stdio.h> int main() { double number; p ...
- maven scope 以及依赖传递
https://www.cnblogs.com/mxm2005/p/4947905.html
- Django一些鲜为人知的操作
目录: - Django ORM执行原生SQL - QuerySet方法大全 一.Django ORM执行原生SQL # extra # 在QuerySet的基础上继续执行子语句 # extra(se ...
- c#字符串字面量
分为两种: 1 常规字符串字面量 2逐字字面量字符串:以@字符为前缀.注意:注意逐字字面量唯一例外的是相邻的双引号组,它们被解释为单个双引号字符.
- Linux systemd 常用命令
系统管理 systemctl 显示系统状态: $ systemctl status 立即激活单元: # systemctl start [单元] 立即停止单元: # systemctl stop [单 ...
- NET Core应用中实现与第三方IoC/DI框架的整合?
NET Core应用中实现与第三方IoC/DI框架的整合? 我们知道整个ASP.NET Core建立在以ServiceCollection/ServiceProvider为核心的DI框架上,它甚至提供 ...
- Linux之shell命令实现-批量去掉文件名中空格,以及批量修改文件名为数字序号文件名
1 shell下批量出去文件名中的空格 执行看现象: 上面的是执行for循环以后看到的: 然而源目录下的文件如下: 这样的话想要cat某个具体文件是拿不到的,所以需要去空格处理: 处理方式有很多:如 ...
- NHibernate中创建User类报错问题
前两天刚开始学习NHibernate架构,照着前辈的例子打了一遍运行之后没问题,然后自己创建了一个User的Model发现一运行就报User附近有错误,然后就检查,类写的没错用了virtual,Use ...