raywenderlich-iOS设计模式Part 1/2【译】

原文地址:http://www.raywenderlich.com/86477/introducing-ios-design-patterns-in-swift-part-1

Update 04/22/2015: Updated for Xcode 6.3 and Swift 1.2.

Update note: This tutorial was updated for iOS 8 and Swift by Vincent Ngo. Original Post by Tutorial team member Eli Ganem.

*************原文只有swift版本,我顺便添加OC版本,因为不了解swift,所以我写的OC代码可能会有错,请见谅************



设计模式是在软件设计中对常见问题的复用解决方案,是帮助你写出便于理解与复用的代码的模板,也帮助你写出低耦合代码以便较为轻松地变更代码内容。

在这篇分为两个部分的教程中,你会创建一个Music Library app(音乐库应用),这个应用会展示音乐专辑和相关信息。

在开发这个app的过程中,你会熟悉最常用的Cocoa设计模式:

  • Creational(创建型): Singleton(单例模式)
  • Structural(结构型): MVC, Decorator(装饰模式), Adapter(适配器模式), Facade(外观模式).
  • Behavioral(行为型): Observer(观察者模式),Memento(备忘录模式)

不要误以为这篇文章是走理论的;你在这个app中会用到大部分上面的设计模式,你的app最后会是这样:

下载starter project,解压,在Xcode中打开BlueLibrarySwift.xcodeproj



此项目有三个重点:

1. 有两个IBOutlet连接到ViewController,一个是table view,一个是toolbar

2. storyboard有三个部分,已经为AutoLayout创建了约束,顶部部分是展示专辑封面的地方;封面下的部分是table view,展示专辑相关信息;最后一个部分是toolbar,有两个button,从图上可以看到:一个undo,一个删除。

3. 一个HTTP Client类(HTTPClient),类的实现由你稍后来编写。

Note:你知道当你创建一个新的Xcode项目时,你的代码就已经带有设计模式了吗?MVC,Delegate,Protocol,Singleton - 你直接得到了

在深入第一种设计模式前,需要先创建两个类分别存储,展示数据


  • 新建:File\New\File…(或者按快捷键 Command+N).选择 iOS > Cocoa Touch Class ,点击Next. 类名写为Album,NSObject的子类. 最后:选择语言为Swift,点击Next,Create.
  • 打开Album.swift,添加下列属性。
 1 // swift
 2
 3 var title : String!
 4 var artist : String!
 5 var genre : String!
 6 var coverUrl : String!
 7 var year : String!
 8
 9 // Objective-C
10
11 @property (nonatomic,copy) NSString *title;
12 @property (nonatomic,copy) NSString *artist;
13 @property (nonatomic,copy) NSString *genre;
14 @property (nonatomic,copy) NSString *coverUrl;
15 @property (nonatomic,copy) NSString *year;

创建了5个属性,Album类将会实时关注这5个属性。

  • 接下来添加Album对象初始化方法
// Swift

init(title: String, artist: String, genre: String, coverUrl: String, year: String) {
    super.init()
    self.title = title
    self.artist = artist
    self.genre = genre
    self.coverUrl = coverUrl
    self.year = year
}

// Objective-C

// Album.h
+(Album *)initWithTitle:(NSString *) title artist:(NSString *)artist genre: (NSString *)genre coverUrl:(NSString *)coverUrl year:(NSString *)year;

// Album.m
+(Album *)initWithTitle:(NSString *) title artist:(NSString *)artist genre: (NSString *)genre coverUrl:(NSString *)coverUrl year:(NSString *)year{

    if(self = [super init]){
         self.title = title
         self.artist = artist
         self.genre = genre
         self.coverUrl = coverUrl
         self.year = year
     }

 }
  • 重写description方法
// Swift

override var description: String {
    return "title: \(title)" +
           "artist: \(artist)" +
           "genre: \(genre)" +
           "coverUrl: \(coverUrl)" +
           "year: \(year)"
}

// Objective-C

(NSString *)description{
    return [NSString stringWithFormat:@"title:%@,artist:%@,genre:%@,coverUrl:%@,year:%@",self.title,self.artist,self.genre,self.coverUrl,self.year];
}

description方法以字符串形式返回Album对象的属性。


  • 建立第二个类,把类名设定为AlbumView,继承自UIView
 1 // Swift
 2
 3 private var coverImage: UIImageView!
 4 private var indicator: UIActivityIndicatorView!
 5
 6 // Objective-C
 7 // 写到.m文件里
 8
 9 @implementatin AlbumView
10
11 @property (nonatomic,weak) UIImageView *coverImage;
12 @property (nonatomic,weak) UIActivityIndicatorView *indicator;
13
14 @end

coverImage是专辑封面图片,第二个属性是实时跟踪封面加载情况的活动指示器

这两个属性设定为私有类型是因为在AlbumView类之外的地方不需要知道这两个属性的存在,它们只是用在内部实现功能里。当你要创建一个供大家使用的库或者框架时使用这个非常重要的规则就能保持私有变量信息不公开。

  • 同样,为AlbumView类添加初始化方法
required init(coder aDecoder: NSCoder) {
  super.init(coder: aDecoder)
  commonInit()
}

init(frame: CGRect, albumCover: String) {
  super.init(frame: frame)
  commonInit()
}

func commonInit() {
  backgroundColor = UIColor.blackColor()
  coverImage = UIImageView(frame: CGRect(x: 5, y: 5, width: frame.size.width - 10, height: frame.size.height - 10))
  addSubview(coverImage)
  indicator = UIActivityIndicatorView()
  indicator.center = center
  indicator.activityIndicatorViewStyle = .WhiteLarge
  indicator.startAnimating()
  addSubview(indicator)
}

// 然而已经不知道OC应该怎么写。

NSCoder需要被初始化因为UIView遵从NSCoding

commonInit是一个辅助方法,它被用到了两个init方法当中,你之后会需要这些方法,设定AlbumView的默认条件。背景黑色,为imageView设置5个像素的边缘,以及将coverImage和indicator属性添加到父视图。

  • 最后:添加下列方法
// Swift  

func highlightAlbum(#didHighlightView: Bool) {
    if didHighlightView == true {
      backgroundColor = UIColor.whiteColor()
    } else {
      backgroundColor = UIColor.blackColor()
    }
  }

//OC

- (void) highlightAlbum:(BOOL)didHighlightView{
     if([self didHighlightView]){
         self.view.coverImage.backgroundColor = [UIColor whiteColor];
     }else{
         self.view.coverImage.backgroundColor = [UIColor blackColor];
     }
 }

高亮时专辑封面为白色,反之为黑色。

编译工程,确保一切都没有问题,然后准备开始第一个设计模式的学习。


MVC – The King of Design Patterns 设计模式王者

MVC是Cocoa的基石,毫无疑问它是被运用最多的设计模式。它按照对象的常规角色对对象进行分类,且鼓励开发者这样为代码创建目录以保证项目层次清晰明确。

这三种角色分别是:

  • Model(模型):Model对象存储应用数据,定义管理这些数据的方法,就像在这个项目中你的Album类。
  • View(视图):View对象负责把Model和与用户的交互借口视觉呈现出来,基本上就是所有的UIView衍生出的对象,就像这个项目中你的AlbumViw类。
  • Controller(控制器):Controller对象是协调以上工作的媒介,它拿到Model的数据然后在View中将之呈现出来,还有监听交互情况并按照它管理数据,现在你知道你的项目中的Controller是谁了吗?没错,就是ViewController。

要想实现好这个设计模式,就要把每个对象都分配到Model,View,Controller组中。

下图可以描述MVC的关系:

当Model对象的数据发生改变时,它会通知Controller对象,然后Controller对象更新对应的View对象上展示的数据。当用户在View对象进行了交互操作时,View对象会通知Controller对象,然后Controller对象会更新对应的Model对象中的数据。

未完待续 第一次更新:2016-03-02 11:58:18

时间: 2024-08-02 13:47:51

raywenderlich-iOS设计模式Part 1/2【译】的相关文章

IOS设计模式之二(门面模式,装饰器模式)

本文原文请见:http://www.raywenderlich.com/46988/ios-design-patterns. 由 @krq_tiger(http://weibo.com/xmuzyq)翻译,如果你发现有什么错误,请与我联系谢谢. 门面(Facade)模式(译者注:facade有些书籍译为门面,有些书籍译为外观,此处译为门面) 门面模式针对复杂的子系统提供了单一的接口,不需要暴漏一些列的类和API给用户,你仅仅暴漏一个简单统一的API. 下面的图解释了这个概念: 这个API的使用者

IOS设计模式之四(备忘录模式,命令模式)

本文原文请见:http://www.raywenderlich.com/46988/ios-design-patterns. 由 @krq_tiger(http://weibo.com/xmuzyq)翻译,如果你发现有什么错误,请与我联系谢谢. 备忘录(Memento)模式 备忘录模式快照对象的内部状态并将其保存到外部.换句话说,它将状态保存到某处,过会你可以不破坏封装的情况下恢复对象的状态,也就是说原来对象中的私有数据仍然是私有的. 如何使用备忘录模式 在ViewController.m中增加

IOS设计模式之三(适配器模式,观察者模式)

本文原文请见:http://www.raywenderlich.com/46988/ios-design-patterns. 由 @krq_tiger(http://weibo.com/xmuzyq)翻译,如果你发现有什么错误,请与我联系谢谢. 适配器(Adapter)模式 适配器可以让一些接口不兼容的类一起工作.它包装一个对象然后暴漏一个标准的交互接口. 如果你熟悉适配器设计模式,苹果通过一个稍微不同的方式来实现它-苹果使用了协议的方式来实现.你可能已经熟悉UITableViewDelegat

IOS设计模式之一(MVC模式,单例模式)

本文原文请见:http://www.raywenderlich.com/46988/ios-design-patterns. 由 @krq_tiger(http://weibo.com/xmuzyq)翻译,如果你发现有什么翻译错误,请与我联系谢谢. iOS 设计模式-你可能已经听说过这个词,但是你真正理解它意味着什么吗?虽然大多数的开发者可能都会认为设计模式是非常重要的,然而关于设计模式这一主题的文章却不多,并且有时候我们开发者在写代码的时候也不会太关注它. 在软件设计领域,设计模式是对通用问题

iOS设计模式(代码分析系列2:简单工厂模式)

简单工厂模式示例代码下载地址, 1.简述 首先需要说明一下,简单工厂模式不属于23种GOF设计模式之一.它也称作静态工作方法模式,是工厂方法模式的特殊实现(也就是说工厂模式包含简单工厂模式).这里对简单工厂模式进行介绍,是为后面的工厂方法和抽象工厂模式做一个引子. 2.定义 "专门定义一个类来负责创建其他类的实例,被创建的实例通常具有共同的父类." 世界上就是由一个工厂类,根据传入的参数,动态地决定创建出哪一个产品类的实例. 3.结构图 简要分析结构图: ConcreteProduct

IOS设计模式之三:MVC模式

IOS设计模式之三:MVC模式 提到ios中的mvc不得不提2011秋季斯坦福课程的老头,他的iphone开发公开课是所有描述ios中mvc模式最为准确并且最为浅显易懂的. 模型-视图-控制器 这个模式其实应该叫做MCV,用控制器把model与view隔开才对,也就是model与view互相不知道对方的存在,没有任何瓜葛,他们就像一个团队里吵了架的同事,如果有项目需要他俩来参与,那么最好有第三者来管理他俩之间的沟通与协调.这个第三者就是控制器. 既然管理,那么姑且就把这个控制器提做项目经理吧,这

iOS设计模式 - (3)简单工厂模式

iOS设计模式 - (3)简单工厂模式           by Colin丶 转载请注明出处:              http://blog.csdn.net/hitwhylz/article/details/40381721 一.简述 简单工厂模式(FACTORY),通过面向对象的封装,继承和多态来降低程序的耦合度.将一个具体类的实例化交给一个静态工厂方法来执行. 该模式中的角色包括: 工厂类(Simple Factory): 只包含了创建具体类的静态方法. 抽象产品(Product):

iOS设计模式

iOS设计模式,很多开发这都是听得多,但是有时候自己即使用过也不会很在意,开发者在写代码的时候也不会注意它. 在软件设计领域,设计模式是对通过问题的可复用的解决方案.设计模式是一系列帮你写出可理解和复用的模板,设计模式帮你创建松耦合的代码,你不需要花费太多就可以改变或者替换代码中的组件. (1)代理模式 应用场景:当一个类的某些功能需要由其他别的类别来实现的,但是又不确定是哪个类 优势:松耦合 实例:tableView的数据源delegate,通过和protocol的配合,完成委托. 列表row

iOS设计模式之生成器

iOS设计模式之生成器 1.生成器模式的定义 (1): 将一个复杂的对象的构件与它的表示分离,使得相同的构建过程能够创建不同的表示 (2): 生成器模式除了客户之外还包括一个Director(指导者),和一个builder(生成器).client通过向指导者(Director)提出需求,指导者(Director)向bulider(生成器)提供信息来建造特定的产品.bulider依据特定的信息生产产品并返回给客户. 2:使用生成器的优点 构建某些对象有多种不同的方式,假设这些逻辑包括在构建这些对象

iOS 设计模式

Ios 设计模式,你可能听说过,但是你真正知道这是什么意思么?大部分的开发者大概都同意设计模式很重要,但是关于这一部分却没有很多的文章去介绍它,我们开发者很多时候写代码的时候也并不重视设计模式. 设计模式是在软件设计上去解决普通问题的可重用的方法.他们是是帮助你让所写的代码更加容易理解和提高可重用性的模板.它们还可以帮你创建松散耦合的代码是你能不费很大功夫就可以改变或者替代你的代码中的一部分. 如果你对设计模式感到生疏,那么我有个好消息告诉你!首先,你已经用了很多ios设计模式多亏了Cocoa