读书人

iOS设计模式之二(门脸模式装饰器模

发布时间: 2013-11-08 17:52:14 作者: rapoo

iOS设计模式之二(门面模式,装饰器模式)
门面(Facade)模式(译者注:facade有些书籍译为门面,有些书籍译为外观,此处译为门面)iOS设计模式之二(门脸模式,装饰器模式)门面模式针对复杂的子系统提供了单一的接口,不需要暴漏一些列的类和API给用户,你仅仅暴漏一个简单统一的API。 下面的图解释了这个概念:iOS设计模式之二(门脸模式,装饰器模式) 这个API的使用者完全不需要关心背后的复杂性。这个模式非常适合有一大堆很难使用或者理解的类的情况。 门面模式解耦了使用系统的代码和需要隐藏的接口和实现类。它也降低了外部代码对内部子系统的依赖性。当隐藏在门面之后的类很容易发生变化的时候,此模式就很有用了,因为当背后的类发生变化的时候,门面类始终保持了同样的API。 举个例子来说,如果有一天你想取代后端服务,你不需要改变API的使用者,因为API没有发生变化。 如何使用门面模式 当前你已经用PersistencyManager本地保存专辑数据,使用HTTPClient处理远程连接,工程中的其它类暂时与本次实现的逻辑无关。 为了实现这个模式,只有LibraryAPI应该保存PersistencyManager和HTTPClient的实例,然后LibraryAPI将暴漏一个简单的API去访问这些服务。 注意: 通常来说,单例类的生命周期贯穿于整个应用的生命周期中,你不应对保存太多其它对象的强引用,因为他们只有到应用关闭的时候才能被释放。 本次设计看起来像下图:iOS设计模式之二(门脸模式,装饰器模式) LibraryAPI将暴漏给其它代码,但是它隐藏了HTTPClient和PersistencyManager的复杂性。 打开LibraryAPI.h,在文件头部增加下面的导入语句:#import "Album.h" 接下来,在LibraryAPI.h中增加如下的方法定义:

    接下来,你将需要在屏幕上显示专辑数据,使用你的下个设计模式-装饰器设计模式将是非常好的选择。 装饰器—ecorator)模式装饰器模式在不修改原来代码的情况下动态的给对象增加新的行为和职责,它通过一个对象包装被装饰对象的方法来修改类的行为,这种方法可以做为子类化的一种替代方法。 在Objective-C中,存在两种非常常见的实现:Category(类别)和Delegation(委托)。 Category(类别) Category(类别)是一种不需要子类化就可以让你能动态的给已经存在的类增加方法的强有力的机制。新增的方法是在编译期增加的,这些方法执行的时候和被扩展的类的其它方法是一样的。 它可能与装饰器设计模式的定义稍微有点不同,因为Category(类别)不会保存被扩展类的引用。 注意: 你除了可以扩展你自己的类以外,你还可以给Cocoa自己的类增加方法。 如何使用类别设想一种情况,你需要让Album(专辑)对象显示在一个表格视图(TableView)中:iOS设计模式之二(门脸模式,装饰器模式)专辑的标题从何而来?因为专辑是模型对象,它本身不需要关心你如何显示它的数据。你需要增加一些代码去扩展专辑类的行为,但是不需要直接修改专辑类。 你将创建一个专辑类扩展的类别,它将定义一个新的方法,这个方法会返回能很容易和UITableViews使用的数据结构。这个数据结构如下图所示:iOS设计模式之二(门脸模式,装饰器模式) 为了给Album增加一个类别,导航到“File\New\File...\",选择Objective-C category模板,不要习惯性的选择Objective-C class模板。在Category域输入TableRepresentation,Category on域输入Album。 注意:你已经注意到了新建文件的名字了吗?Album+TableRepresentation意味着你正在扩展Album类。这种约定是非常重要,因为它方便阅读以及阻止和你或者其他人创建的类别冲突。 打开Album+TableRepresentation.h类,新增如下的方法原型:
      UITableView的职责就是显示一个表格视图。然而最终它需要一些它自身没有的信息。那么它就求助于它的委托,通过发送消息给委托来获取信息。在Objective-C实现委托模式的时候,一个类可以通过协议(Protocol)来声明可选以及必要的方法。本指南稍后会涉及协议方面的内容。 子类化一个对象,复写需要的方法看起来好像更容易一点,但是考虑到你只能子类化一个类,如果你想一个对象作为两个或者更多对象的委托的话,使用子类化将不能实现。 注意:这个是一个重要的模式。苹果在UIKit类中大量使用了它:UITableView, UITextView, UITextField, UIWebView, UIAlert, UIActionSheet, UICollectionView, UIPickerView,UIGestureRecognizer, UIScrollView等等等。 如何使用委托模式打开ViewController.m文件,在文件开头增加下面的导入语句:
        这里出了什么问题?你声明ViewController作为UITableView的委托和数据源,但是这样做了,也就意味着你必须实现所必须的方法-这些方法包括你还没有实现的tableView:numberOfRowsInSection:方法. 在ViewController.m文件中@implementation 和@end 之间的任何位置,增加下面的代码:
          到目前为止进展挺顺利。但是你回忆第一张本app最终效果的图,你会发现在屏幕顶部有一个水平滚动视图在不同的专辑之间切换。并不是构建一个只为这次使用的单一目的的水平滚动视图,你为什么不做一个可以让任何视图复用的滚动视图呢? 为了使这个视图可以复用,应该由委托来决定所有的从左边开始依次到下一个对象的内容。水平滚动条应该声明那些能和它一起工作的委托方法,这有点类似UITableView的委托方法的方式。我们将在讨论下一个模式的时候来实现它。

读书人网 >操作系统

热点推荐