网站大量收购独家精品文档,联系QQ:2885784924

浅析装饰者模式.pdf

  1. 1、本文档共6页,可阅读全部内容。
  2. 2、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
  3. 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载
  4. 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
查看更多
装饰者模式

装饰者模式 装饰者模式 - Decorator 装饰者模式可以动态的给指定的类添加⼀些⾏为和职责,⽽不⽤对原代码 ⾏任何修 改。当你需要使⽤⼦类的时候,不妨考虑⼀下装饰者模式,可以在原始类上⾯封装⼀ 层。 在 Swift ⾥,有两种⽅式实现装饰者模式:扩展 (Extension) 和委托 (Delegation) 。 扩展 扩展是⼀种⼗分强⼤的机制,可以让你在不⽤继承的情况下,给已存在的类、结构体 或者枚举类添加⼀些新的功能。最重要的⼀点是,你可以在你没有访问权限的情况下 扩展已有类。这意味着你甚⾄可以扩展 Cocoa 的类,⽐如 UIView 或者 UIImage 。 举个例⼦,在编译时新加的⽅法可以像扩展类的正常⽅法⼀样执⾏。这和装饰器模式 有点不同,因为扩展不会持有扩展类的对象。 如何使⽤扩展 想象⼀下这个场景,我们需要在下⾯这个列表⾥展⽰数据: 专辑标题从哪⾥来? Album 本⾝是个 Model 对象,所以它不应该负责如何展⽰数 据。你需要⼀些额外的代码添加展⽰数据的逻辑,但是为了保持 Model 的⼲净,我 们不应该直接修改代码,因为这样不符合单⼀职责原则。 Model 层最好就是负责纯 粹的数据结构,如果有数据的操作可以放到扩展中完成。 接下来我们会创建⼀个扩展,扩展现有的 Album 类,在扩展⾥定义了新的⽅法,返 回更适合 UITableView 展⽰⽤的数据结构。 数据的结构⼤概是这样: 新建⼀个 Swift ⽂件:AlbumExtensions ,在⾥⾯添加如下扩展: extension Album { func ae_tableRepresentation( - (titles:[String], values:[Strin return ([Artist, Album, Genre, Year], [artist, title, } } 在⽅法的前⾯有个 ae_ 前缀,是 AlbumExtension 的缩写,这样有利于和类的原有 ⽅法 ⾏区分,避免使⽤的时候产⽣冲突。现在很多还在维护中的第三⽅库都已经改 成了这个风格。 注意:类是可以重写⽗类⽅法的,但是在扩展⾥不可以。扩展⾥的⽅法和属性不能和 原始类⾥的⽅法和属性冲突。 思考⼀下这个设计模式的强⼤之处: 我们可以直接在扩展⾥使⽤ Album ⾥的属性。 我们给 Album 类添加了内容但是并没有继承它,事实上,使⽤继承来扩展业务 也可以实现⼀样的功能。 这个简单的扩展让我们可以更好地把 Album 的数据展⽰在 UITableView ⾥,⽽且不⽤修改源码。 委托 装饰者模式的另⼀种实现⽅案是委托。在这种机制下,⼀个对象可以和另⼀个对象相 关联。⽐如你在⽤ UITableView ,你必须实现 tableView(_:numberOfRowsInSection: 这个委托⽅法。 你不应该指望 UITableView 知道你有多少数据,这是个应⽤层该解决的问题。所 以,数据相关的计算应该通过 UITableView 的委托来解决。这样可以让 UITableView 和数据层分别独⽴。视图层就负责显⽰数据,你递过来什么我就显⽰ 什么。 下⾯这张图很好的解释了 UITableView 的⼯作过程: UITableView 的⼯作仅仅是展⽰数据,但是最终它需要知道⾃⼰要展⽰那些数据, 这时就可以向它的委托询问。在 objc 的委托模式⾥,⼀个类可以通过协议来声明可选 或者必须的⽅法。 看起来似乎继承然后重写必须的⽅法来的更简单⼀点。但是考虑⼀下这个问题:继承 的结果必定是⼀个独⽴的类,如果你想让某个对象成为多个对象的委托,那么⼦类这 招就⾏不通了。 注意:委托模式⼗分重要,苹果在 UIKit 中⼤量使⽤了该模式,基本上随处可见。 如何使⽤委托模式 打开 ViewController.swift ⽂件,添加如下私有变量: private var allAlbums = [Album]( private var currentAlbumData : (titles:[String], values:[String] ? private var currentAlbumIndex = 0 在 viewDidLoad ⾥⾯加⼊如下内容: override func viewDidLoad( { super.viewDidLoad( self.navig

文档评论(0)

aena45 + 关注
实名认证
内容提供者

该用户很懒,什么也没介绍

1亿VIP精品文档

相关文档