swift中得ios设计模式

前端之家收集整理的这篇文章主要介绍了swift中得ios设计模式前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

原文链接http://letsswift.com/2015/01/ios-design-pattern-in-swift-1/

OS设计模式- 大伙应该都听说过,但是有多少人真正的了解他们呢?虽然大多数开发者都认同设计模式的重要性,但是在实际开发中却并不怎么注意使用设计模式,而且关于设计模式的文章也是凤毛麟角,这更使得开发者无从下手去学习设计模式。

设计模式是一个处理软件设计中常见问题的解决方法,并可以重复使用。它向开发者提供了设计模板,使开发者更容易写出逻辑清晰、具有可复用性的代码。它还可以使代码具有松耦合性,能让开发者轻松的更新或替换项目中使用的组件。

在本教程中,大伙要开发一个音乐仓库应用,能显示你们收藏的专辑以及相关信息。

在开发过程中,大伙会逐渐掌握大多数通用的Cocoa设计模式:

  • 构建设计模式:Singleton。
  • 架构设计模式:MVC,Decorator,Adapter,Facade。
  • 行为设计模式:Observer,Memento。

千万不要认为该文章只是对设计模式理论上的讲解,大伙需要在你们的音乐仓库应用中运用到这些设计模式。你们的应用最终看起来大概是这个模样:

准备开始

从这里下载初始项目,解压Zip文件,然后在Xcode中打开BlueLibrarySwift.xcodeproj工程。

在开始之前,有三件事需要大伙注意:

  • ViewController中有两个IBOutlet连接着Storyboard中的TableView和Toolbar。
  • 在Storyboard中的ViewController里含有三个组件,并且设置了AutoLayout布局约束。最上面的组件用来显示音乐专辑的封面。中间是一个TableView,用来显示与该专辑相关的信息。最下面是两个Toolbar按钮,一个是撤销操作按钮,另一个是删除选中专辑的按钮。你们的Storyboard看起来应该是下面这个样子:

  • 在工程里还有一个HTTP Client类(HTTPClient),这个类目前是空的,但是你们在之后会充实它。

注意:你们知道吗,当你们创建了一个新的Xcode项目后,你们所编写的代码其实就已经在遵循一定的设计模式了,Model-View-Controller,Delegate,Protocol,Singleton这些设计模式统统可以免费使用哦。

在带你们深入了解第一个设计模式之前,你们需要创建两个类,用于存储和展示音乐专辑的数据。

点击菜单File\New\File…(或者按下Command+N快捷键)。选择iOS > Cocoa Touch Class,点击Next。设置该类的名称Album,并让它继承NSObject。最后选择语言为Swift然后点击Next,最后点击Create

打开Album.swift文件,在Album类中定义如下属性

var title : String! artistgenrecoverUrlyear!

然后添加一个初始化方法

init(title String,artistgenrecoverUrlyear){ super.()self. = }

这段代码Album类创建了一个初始化方法,当你要创建一个新的专辑时你要通过这个初始化方法,传入专辑名称、演唱者、风格、专辑封面图片的URL以及年份这些属性

接下来需要再添加一个方法

funcdescription-> Stringreturn "title: \(title)"+"artist: \(artist)""genre: \(genre)""coverUrl: \(coverUrl)""year: \(year)" description()方法将专辑的这些属性拼成一个字符串,并返回。

我们再次通过刚才创建类的步骤创建一个名为AlibumView的类,注意该类要继承UIView

打开AlbumView.swift文件,在该类中添加两个属性

privateletcoverImage UIImageView indicatorUIActivityIndicatorViewcoverImage属性用来展示专辑封面,indicator是当正在下载封面图片时转动的菊花。

大伙注意,这里的两个属性分配了private访问级别,也就是说这两个属性只能在AlbumView.swift文件中使用,因为其他的类压根没有必要知道这两个属性的存在。(译者:其实这里用不用private都无所谓,因为咱们写的又不是library或者framework。)

接下来为AlbumView添加初始化方法

required (coderaDecoderNSCodercoder}frameCGRectalbumCoverbackgroundColorUIColorblackColorcoverImageUIImageView CGRectMake(5 sizewidth-10height))addSubviewindicatorUIActivityIndicatorViewcenteractivityIndicatorViewStyle.WhiteLargestartAnimating 由于UIView遵循了NSCoding,而AlbumView又继承了UIView,所以这里需要写一个NSCoder的初始化方法,但我们不会在这个方法中处理什么逻辑,所以调用super.init即可。

AlbumView真正的初始化方法是另外一个init方法,在这个方法中设置了一些默认的属性,比如将背景色设置为黑色、实例化了coverImage属性,并让它与父容器有5px的四周间距、实例化indicator并设置位置及风格。

最后再添加一个方法

highlightAlbum(#didHighlightView: Bool) ifdidHighlightView==truewhiteColorelse 这个方法是专辑封面高亮开关,高亮时专辑封面背景色为白色,否则为黑色。

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

设计模式的王者 – MVC模式

Model-View-Controller (MVC)设计模式是Cocoa框架的基石,毋庸置疑它是开发者们最常用的设计模式没有之一。它把应用中的对象按它们的角色进行分类,并鼓励开发者按这种角色分类创建项目目录,将代码放置在合适的位置,保证项目结构清晰明确。

顾名思义,MVC中有三种角色:

  • Model:这种对象保存应用程序的数据,并定义如何操作处理这些数据。比如之前你们创建的Album类就是一个Model对象。
  • View:这种对象主要负责Model对象的呈现,以及用户交互。基本上,由UIView衍生出的类都是View对象。在你们的音乐仓库应用中AlbumView就是一个View对象。
  • Controller:这种对象充当着应用程序的协调者,由它来协调所有的事情。它会访问Model对象的数据,然后展示在相应的View对象中;它也会监听用户在View对象上的交互,从而通知Model对象进行相应的数据操作等等。你们应用中的ViewController就是一个Controller对象。

下图可以很好的说明Model对象和View对象是如何通过Controller对象进行通信的:

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

你们可能会有这样的疑惑,为什么不把这些操作处理都写在Controller对象中呢,这样就不用通知通知去的,不是更简单吗?

我告诉你们两个概念,你们就明白这样做的目的了,那就是低耦合性和高复用性。我举个例子,在一个应用中每个界面中的数据大多数是来自于多个Model对象,如果把View对象和Model对象绑定死了,那么就没法处理这种情况了。

拿咱们这个音乐仓库的应用来说,如果你们以后想做一个电影仓库或者图书仓库,你仍然可以使用AlbumView这个View对象来展示你的电影或者图书Model对象。假如你的电影仓库应用需要展示电影主题曲的一些信息,那么或许你就可以直接复用Album对象,因为Album对象不依赖于任何View对象。这就是MVC设计模式的强大之处。

如何使用MVC设计模式

首先,你要确保项目中每个类的功能,要么是Controller,要么是View,要么是Model。千万不要将两种角色混合于一个类,每个类只有单一的职责。不过,到目前为止,你们已经创建了标准的Model类Album和View类AlbumView

其次,为了使项目目录结构清晰明了,以及能够更感官的实行MVC模式,你们需要在工程中创建三个文件组,来区分开这三种角色的文件

通过File\New\Group(或同时按下Command+Option+N)在工程中创建一个名为Model文件组,然后以同样的方式创建View文件组和Model文件组。

最后将Album.swift文件拖进Model文件组,将AlbumView.swift文件拖进View文件组,将ViewController.swift文件拖进Model文件组。

此时,你们的项目目录结构应该是这样的:

现在的项目结构看起来已然井然有序,当然你们还可以创建其他的文件组和类文件,但是要记住的是,Model、View、Controller这三个文件组是整个程序的核心所在。

现在项目结构已经理清楚了,接下来的工作就需要从某个地方获取到专辑的相关数据。你们可以创建一个名为API的类,用于负责整个应用的数据管理工作。并且将拉开你们要了解的下一个设计模式 — Singleton。

Singleton设计模式

单例模式使一个类在整个应用生命周期内只存在一个实例,并且有一个全局的方法来访问这个实例。在单例模式下,当第一次访问某个类的实例时,该类通常使用延迟加载的方式创建该类的单例。

注意:Apple在iOS和OSX中大量使用了单例模式,比如:NSUserDefaults.standardUserDefaults()UIApplication.sharedApplication()UIScreen.mainScreen()NSFileManager.defaultManager()

你们可能会有疑问,为什么我们要这么在意一个类有一个或多个实例?代码和内存现在是如此的廉价,不是么?

其实不然,有些情况下,确实只需要类实例化一次,且仅有一次。比如有这么一种情况,在一个应用的生命周期里,应用(Application)设备的主屏幕是只存在一份的,那么你当然希望应用和设备屏幕的实例有且只有一个。或者你需要一个全局的处理配置的类,这样能线程安全的访问配置文件,避免多个配置类同时访问一个配置文件。这些就是单例模式的好处所在。

如何使用Singleton设计模式

先看看下面这张图:

上图是Logger的类图,从图中可以看出,Logger有一个instance属性以及sharedInstanceinit两个方法

当第一次调用sharedInstance方法时,instance属性还没有初始化,所以你会创建一个新的Logger类实例,并返回一个该实例的引用。

当再次调用instance属性会立即返回,并且不需要再进行任何实例化操作。这个逻辑就保证了Logger类的实例有且仅有一份。

你们将要通过Singleton设计模式,创建一个单例的类用于管理所有专辑的数据。

你们应该注意到了,在项目的目录结构中,有一个文件组叫做API,这个文件组里存放的类基本都是为应用提供服务的类。我们在这个文件组中创建一个名为LibraryAPI的类。

打开LibraryAPI.swift文件添加如下代码

//1classsharedInstance LibraryAPI //2struct Singleton//3staticinstance LibraryAPI//4 Singleton}
  1. 创建一个类变量的计算属性。类变量类似Objective-C中的类方法,也就是说在任何时候你访问sharedInstance属性时,都不需要对LibraryAPI进行实例化,关于属性类型更多的知识请参阅Swift文档 –properties
  2. 在类变量中内嵌一个结构体,名为Singleton
  3. Singleton中包含一个名为instance的静态常量属性。用static申明属性意味着该属性只能存在一份。这里要注意的是Swift中的静态属性都会延迟加载,也就是说只有instance被使用时,才会初始化它。还要注意的一点是,一旦instance被初始化了,那么它就是一个常量属性,不会有第二次初始化的机会了。这就是Singleton模式的精髓所在。
  4. 返回该计算属性的值。

注意:如果想了解Swift中创建单例的其他方法请参阅这里:Github page

你们现在已经有一个单例模式的对象,作为管理专辑数据的入口。接下来要更进一步,创建一个类,用于处理你们数据的持久性。

继续在API这个文件组中创建一个类,名为PersistencyManager,并让它继承NSObject类。

打开PersistencyManager.swift文件,申明一个属性

albums[Album]()

这里申明了一个private访问权限的变量属性,用于储存专辑数据。这个数组是可变数组,所以你们可以很轻松的增删专辑。

接下来我们在该类中添加如下初始化方法

override//Dummy list of albumsalbum1 Album"Best of Bowie""David Bowie""Pop""http://www.coversproject.com/static/thumbs/album/album_david%20bowie_best%20of%20bowie.png""1992"album2"It's My Life""No Doubt""http://www.coversproject.com/static/thumbs/album/album_no%20doubt_its%20my%20life%20%20bathwater.png""2003"album3"Nothing Like The Sun""Sting""http://www.coversproject.com/static/thumbs/album/album_sting_nothing%20like%20the%20sun.png""1999"album4"Staring at the Sun""U2""http://www.coversproject.com/static/thumbs/album/album_u2_staring%20at%20the%20sun.png""2000"album5"American Pie""Madonna""http://www.coversproject.com/static/thumbs/album/album_madonna_american%20pie.png"[album1album2album3album4album5] 在初始化方法中,你们可以构建一些专辑添加albums数组中,这里我构建了5个专辑。

然后再添加几个方法

getAlbumsaddAlbumalbumindex Intalbumscount>=insertatIndexappenddeleteAlbumAtIndexremoveAtIndex 这些方法可以让你们方便的存、取、删除album数组中的专辑。

然后编译你们的项目,确保编译通过。此时大伙也许又有了疑问,我们应该如何使用PersistencyManager类呢?别着急,在下一节里,会向大家介绍Facade设计模式,届时你们就会明白LibraryAPIPersistencyManager之间的关系,以及如何使用PersistencyManager了。

猜你在找的Swift相关文章