设计模式:解决编程问题的设计模板

设计模式是一个抽象工具,用于面向对象的软件开发,以及其他领域。它是一个设计模板,在特定背景中,解决一般性的、重复出 现的问题。因此,设计模式是一种针对特定的、具体的设计的准则:在某种意义上,它是模式的“实例化”。在如何应用设计模式上,有一定的灵活性,通常例如程 序设计语言和现有架构等事物,会影响如何应用模式。

有几个设计主题或原则对设计模式产生影响。这些设计原则是构建面向对象系统的经验法则,例如“封装发生变化的系统结构方面”(encapsulate the aspects of system structure that vary) 和“面向接口编程,而非面向实现编程”(program to an interface, not an implementation)。它们表达了重要的见解。例如,封装原则告诉我们,如果隔离并封装系统中发生变化的部分,它们可以独立于系统其他部分进行 变化,特别是如果您为它们定义了不依赖实现特性的接口。您稍后可以修改或扩展这些可变部分,而不影响系统的其他部分。这样一来,您清除了各部分之间的互相 依赖,减少了各部分的耦合性,系统就会变得更加灵活、更容易修改。

这样的优点,让设计模式成了编写软件的重点考虑因素。如果您在应用程序的设计中找到了模式,加以调整和使用,该程序(以及 其所包含的对象和类)在将来需要时复用程度更高、扩展能力更强和更容易修改。此外,基于设计模式的应用程序,与没有基于设计模式的应用程序比较,会更见优 雅和更具效率,因为它们只需较少的代码就能达到同样目的。

您会发现,设计模式的应用贯穿于整个 Cocoa Touch 和 Cocoa 框架、Objective-C 的运行时及程序设计语言自身。您可以几乎“免费”获得部分基于模式的机制,而其他部分则需要您做一些工作。情况合适时,可以将设计模式应用到您自己的应用 程序代码中。如果使用与 Cocoa Touch 和 Cocoa 框架相同的模式,您的代码往往会更好地与框架的代码匹配,运行也更为优雅。

最重要的设计模式:模型-视图-控制器

“模型-视图-控制器”(Model-View-Controller) 设计模式,通常被称为“MVC”,将以下一种角色分配给应用程序中的对象:“模型”、“视图”或“控制器”。模式不仅定义了对象在应用程序中扮演的角色, 还定义了对象之间通信的方式。这三类对象的每一个,都由抽象边界与其他对象分隔,穿过这些边界与其他类型的对象进行通信。应用程序中某一 MVC 类型的对象的集合,有时统称为层,例如模型层。

对于任何 iOS 应用程序或 Mac 应用程序而言,MVC 对一个好的设计至关重要。采用此设计的好处多不胜数。这些应用程序中的很多对象,倾向于更可再用,它们的接口倾向于定义得更好。采用 MVC 设计的应用程序,也比其他应用程序更容易扩展。此外,您的应用程序可以用到的很多技术和架构,都是基于 MVC 的,也要求您的自定对象扮演其中一个 MVC 角色。

模型对象

模型对象封装了应用程序的数据,并定义操控和处理该数据的逻辑和运算。例如,模型对象可能是表示游戏中的角色或地址簿中的联系人。有时应用程序的模型层,实际是相关对象的一个或多个图形。数据载入应用程序后,作为应用程序的持续状态(不论该持续状态是储存在文件中,还是在数据库中)一部分的大部分数据,应该驻留在模型对象中。因为模型对象代表了与特定问题 领域相关的知识和专长,在相似问题领域,就可以重复使用它们。“纯”模型对象应该和视图对象不发生明确连接(视图对象显示其数据并允许用户编辑数据),它 不该管到用户界面和显示的问题。

用户在视图层中所进行的创建或修改数据的操作,通过控制器对象传达出去,最终会创建或更新模型对象。模型对象更改时(例如通过网络连接接收到新数据),它通知控制器对象,控制器对象更新相应的视图对象。

视图对象

视图对象是应用程序中用户可以看见的对象。视图对象知道如何将自己绘制出来,并可能对用户的操作作出响应。视图对象的主要目的,就是显示来自应用程序模型对象的数据,并使该数据可被编辑。尽管如此,在 MVC 应用程序中,视图对象通常与模型对象分离。

因为您通常重新使用并重新配置对象,视图对象保证了应用程序之间的一致性。对于 iOS,UIKit 框架提供了视图类的集合;对于 OS X,AppKit 框架提供了类似的集合。在 UIKit 中,视图对象最终继承自 UIView 类;在 AppKit 中,视图对象最终继承自 NSView 类。

视图对象通过应用程序的控制器对象,了解模型数据的更改,并通过控制器对象,将用户发动的修改(例如,在文本栏输入的文本),传达到应用程序的模型对象。

控制器对象

在应用程序的一个或多个视图对象和一个或多个模型对象之间,控制器对象充当媒介。控制器对象因此是同步管道程序,通过它,视图对象了解模型对象的更改,反之亦然。控制器对象还可以为应用程序执行设置和协调任务,并管理其他对象的生命周期。

控制器对象解释在视图对象中进行的用户操作,并将新的或更改过的数据传达给模型对象。模型对象更改时,一个控制器对象会将新的模型数据传达给视图对象,以便视图对象可以显示它。

委托:代表另一个对象

委托因此是一种将应用程序特定行为加入框架类工作的手段,而无需给该类创建子类。它是一种常见的、强大的设计,来扩展和影响框架的行为。

您应该记得,在编写“您的首个 iOS 应用程序”HelloWorld 时,创建了 HelloWorldAppDelegate 对象。Xcode 自动将其分配为应用程序对象(为框架对象)的委托。应用程序委托可以处理 application:didFinishLaunchingWithOptions:,以及应用程序对象发送给它的其他委托消息。

有两个可编程的组件用于委托。委托类必须定义属性(通过名称为 delegate 的约定),以保存一个指向委托的参考。它还必须声明委托类必须采用的协议(请参阅以下部分以获得有关协议的更多信息)。Cocoa Touch 和 Cocoa 框架的许多类,都提供委托作为一种方式,给应用程序用来增加其特定的框架行为。

协议:使不相关的对象之间能通过继承进行通信

协议是可编程接口的声明,任何类都可以实施它的方法。与协议相关联的类实例,调用协议的方法,并获取由该类正式采用和实现该协议所返回的值。对象之间的此类通信,产生了一个特定目标,例如解析 XML 代码或拷贝对象。协议接口两边的对象可以通过继承,实施远距离彼此相关。协议因此和委托一样,可作为子类化的替换手段,通常是框架实施委托的一部分。

通知中心:通知对事件感兴趣的观察者

通知中心是 Foundation 框架的一个子系统,它向应用程序中注册为某个事件观察者的所有对象广播消息(即通知)。(从编程角度而言,它是 NSNotificationCenter 类的实例)。该事件可以是发生在应用程序中的任何事情,例如进入后台状态,或者用户开始在文本栏中键入。通知是告诉观察者,事件已经发生或即将发生,因此让观察者有机会以合适的方式响应。通过通知中心来传播通知,是增加应用程序对象间合作和内聚力的一种途径。

例如,iOS 应用程序中的视图控制器,可以观察 UIKeyboardWillShowNotification 通知,以调整其视图的几何图形,来容纳虚拟键盘。正如此例所示,通知是一个对象,该对象的名称指明了一个特定事件,以及该事件是已经发生或将要发生。它还将一个引用(指向发布或发送通知的对象)送到通知中心,而它可以包含补充信息字典。

任何对象都可以观察通知,但要做到这一点,该对象必须注册,以接收通知。在注册时,它必须指定选择器,以确定由通知传送所调用的方法;方法签名必须只有一个参数:通知对象。注册后,观察者也可以指定发布对象。

通知中心的通知跟委托消息相似;当某些事件发生时,两者都发送给任意对象。但是,处理通知的方法与委托方法不同,它不能返回值。通过通知中心的通知是同步的,与委托一样。

应用程序的自定对象可定义和发布自己的通知,其他自定对象则可以观察该通知。

目标-操作:事件发生时封装待发送的消息

目标-操作设计在概念上很简单。一个对象储存着组成消息表达 式的元素,某些事件发生时,将这些元素放在一起,并发送一则消息。这些元素为一个选择器,用来确定消息(即操作)和接收消息的对象(即目标)。目标的类会 实现与操作和目标相对应的方法,当它在运行中接收到消息时,会通过执行方法来响应事件。

目标-操作主要是 Cocoa Touch 和 Cocoa 框架中的一种控制功能。控制是用户界面对象,例如用户通过轻按、拖移等进行操控的按钮、滑块或开关,将用户的意图通过信号发送给应用程序。Cocoa Touch 的控制储存了操作和目标;大多数 Cocoa 控制与一个或多个单元对象进行了配对,这些单元对象储存了目标和操作。

一些框架在对象中使用目标-操作而不是控制。例如,在设计手势识别器时,UIKit 框架使用了目标-操作。手势识别对象识别手势后,它将操作消息发送给目标对象

键值观察:值更改时通知观察者

键值观察(Key-value observing,或简称 KVO)允许对象观察另一个对象的属性。该属性值改变时,会通知观察对象。它了解新值以及旧值;如果观察的属性为对多的关系(例如数组),它也要了解哪个 包含的对象发生了改变。KVO 有助于使应用程序变得更内聚,保持模型、控制器和视图层中的对象与改变同步。

NSNotificationCenter 通知相似,多个 KVO 观察者可以观察单一属性。此外,KVO 更动态,因为它允许对象观察任意属性,而不需任何新的 API,例如通知名称。KVO 是一个轻量级点对点通信机制,不允许观察所有实例的特定属性。

ios专题 - 常用设计模式的更多相关文章

  1. IOS开发常用设计模式

    IOS开发常用设计模式 说起设计模式,感觉自己把握不了笔头,所以单拿出iOS开发中的几种常用设计模式谈一下. 单例模式(Singleton) 概念:整个应用或系统只能有该类的一个实例 在iOS开发我们 ...

  2. 开发必看 | iOS开发常用设计模式!

    ios开发学习中,经常弄不清楚ios的开发模式,今天我们就来进行简单的总结和探讨~(一)代理模式 应用场景:当一个类的某些功能需要由别的类来实现,但是又不确定具体会是哪个类实现.优势:解耦合敏捷原则: ...

  3. iOS中MVC设计模式

    在组织大型项目的代码文件时,我们常用MVC的思想.MVC的概念讲起来非常简单,就和对象(object)一样.但是理解和应用起来却非常困难.今天我们就简单总结一下MVC设计理念. MVC(Model V ...

  4. 【iOS 单例设计模式】底层解析与运用

    [iOS 单例设计模式]底层解析与运用 一.单例设计名词解释: (官方解释)单例模式确保一个类只有一个实例,自行提供这个实例并向整个系统提供这个实例.(形象比喻)程序 — 公司   单例实例 - 管理 ...

  5. Android常用设计模式(二)

    Android常用设计模式之观察者模式 观察者设计模式在Android应用中会经常用到,模式原理类似于这样的场景: 用户订报纸,然后在报社登记,报社来统计用户(添加用户),用户也可以取消订阅,报社删除 ...

  6. 代码重构 & 常用设计模式

    代码重构 重构目的 相同的代码最好只出现一次 主次方法 主方法 只包含实现完整逻辑的子方法 思维清楚,便于阅读 次方法 实现具体逻辑功能 测试通过后,后续几乎不用维护 重构的步骤 1  新建一个方法 ...

  7. h5专题常用小代码

    今天把做专题常用的js代码总结出来(持续更新),方便以后直接复制使用,不用老敲啊敲 1.屏幕适配JS代码 <script> var phoneScale = parseInt(window ...

  8. ios中常用数据类型相互转换

    ios中常用数据类型相互转换 //1. NSMutableArray和NSArray互转 // NSArray转为NSMutableArray NSMutableArray *arrM = [arr ...

  9. python之路,Day24 常用设计模式学习

    python之路,Day24 常用设计模式学习   本节内容 设计模式介绍 设计模式分类 设计模式6大原则 1.设计模式介绍 设计模式(Design Patterns) --可复用面向对象软件的基础 ...

  10. iOS中常用的四种数据持久化方法简介

    iOS中常用的四种数据持久化方法简介 iOS中的数据持久化方式,基本上有以下四种:属性列表.对象归档.SQLite3和Core Data 1.属性列表涉及到的主要类:NSUserDefaults,一般 ...

随机推荐

  1. React-native 中的触摸响应功能

    我们在做APP的时候,与桌面应用系统不同的是触摸响应. web页面对触摸响应的支持和原生的APP有着很大的差异. 基本用法 componentWillMount: function() { this. ...

  2. Linux 下 scp 传输文件脚本

    脚本执行效果: (1).远程传输本地 /ora_exp/dmp/CWDB_RAMS_* 文件至 11.4.24.21 的 /ora_exp/dmp 目录下.   脚本编写步骤: 假设 oracle 用 ...

  3. Java数据类型(一)

    1 public class VarDemo 2 { 3 public static void main(String []args){ 4 //先声明后赋值 5 int number; 6 numb ...

  4. 实战:ORACLE SQL Performance Analyzer

    通过 SPA,您能够依据各种更改类型(如初始化參数更改.优化器统计刷新和数据库升级)播放特定的 SQL 或整个 SQL 负载,然后生成比較报告,帮助您评估它们的影响. 在 Oracle Databas ...

  5. android开发 Fragment嵌套调用常见错误

    在activity中有时须要嵌套调用fragment,但嵌套调用往往带来视图的显示与预期的不一样或是fragment的切换有问题.在使用时要注意几点: 1.fragment中嵌套fragment,子f ...

  6. MySQL架构优化实战系列2:主从复制同步与查询性能调优

  7. js倒计时功能

    <input id="countdown" type="text" value="140时50分20秒"> <script ...

  8. php 获取远程图片

    一 function gethttpimage($url){      set_time_limit(0);      if(!empty($url)){        $imgUrl=date('Y ...

  9. DataGrid的ItemCreated和ItemDataBound以及合计平均行

    DataGrid为数据绑定控件,是重量级控件,臃肿,无华不实这么一个控件定位.如果做为管理系统,那么还是可以使用的. 本文只是为了记录ItemCreated和ItemDataBound两个事件的用法. ...

  10. php笔记03:布尔类型,字符串,浮点数

    1.布尔类型 下面情况都是看出false: 布尔类型FALSE自身 整型值为0 浮点型值为0.0 空字符串,以及字符串"0" 不包含任何元素的数组 不包含任何成员变量的对象(仅PH ...