第11章:工厂模式

工厂模式是一种创建模式,它提供了一种在不暴露创建逻辑的情况下制造对象的方法。它涉及两种类型。

  1. 工厂创建对象。

  2. 产品是被创建的对象。

从技术上讲,这种模式有多种 "样式",包括简单工厂、抽象工厂和其他。然而,这些模式都有一个共同的目标:将对象创建逻辑隔离在自己的结构中。

在本章中,你将在上一章的项目Coffee Quest的基础上,学习简单工厂。它创建的对象具有共同的类型或协议,而工厂的类型本身是已知的,并由消费者直接使用。

什么时候应该使用它?

只要你想分离出产品创建逻辑,而不是让消费者直接创建产品,就可以使用工厂模式。

当你有一组相关的产品时,如多态子类或几个实现相同协议的对象,工厂就非常有用。例如,你可以用一个工厂来检查一个网络响应,并把它变成一个具体的模型子类型。

当你有一个单一的产品类型时,工厂也很有用,但它需要提供依赖关系或信息来创建它。例如,你可以用一个工厂来创建 "求职者回应 "的电子邮件。该工厂可以根据求职者是否被接受、拒绝或需要面试来生成电子邮件的详细信息。

Playground示例

打开Starter目录下的IntermediateDesignPattern.xcworkspace,或者从上一章中你自己的playground工作区继续,然后打开Factory页面。如上所述,你将创建一个工厂来生成求职者回复邮件。在代码示例后添加以下内容。

在这里,你已经定义了JobApplicant和Email模型。一个申请人有一个名字、电子邮件和四种状态。根据申请人的状态,电子邮件的主题和messageBody将是不同的。

接下来,添加以下代码。

下面是你在上面做的事情。

  1. 创建一个EmailFactory结构。

  2. 为senderEmail创建一个公共属性。你在EmailFactory的初始化程序中设置这个属性。

  3. 创建一个名为createEmail的函数,接收JobApplicant并返回一个Email。在createEmail中,你已经为JobApplicant的状态添加了一个switch case,为邮件的主题和messageBody变量填充了适当的数据。

现在,电子邮件模板已经构建完毕,是时候对潜在的申请人使用你的工厂了

在你的EmailFactory定义下面添加以下代码。

在这里,你创建了一个名为 "Jackson Smith "的新JobApplicant。接下来,你创建了一个新的EmailFactory实例,最后,你使用该实例根据JobApplicant对象的状态属性来生成邮件。

看来,杰克逊很快就会得到一份工作。他可能因为对设计模式的广泛了解而给雷氏咖啡公司留下了深刻印象,从而使自己从其他申请者中脱颖而出!

你应该注意什么?

不是所有的多态对象都需要一个工厂。如果你的对象非常简单,你总是可以把创建逻辑直接放在消费者那里,比如视图控制器本身。

另外,如果你的对象需要一系列的步骤来构建它,你可能最好使用构建器模式或其他模式来代替。

教程项目

你将继续上一章中的Coffee Quest应用程序。如果你跳过了上一章,或者你想重新开始,请打开Finder并导航到你下载本章资源的地方。然后,在Xcode中打开starter\CoffeeQuest\CoffeeQuest.xcworkspace(不是.xcodeproj)。

注意:如果你选择从新开始,那么你需要打开APIKeys.swift并添加你的Yelp API密钥。关于如何生成,请参见第10章 "模型-视图-视图模型模式 "的说明。

你将使用工厂模式来改进根据Yelp评级改变图标背后的机制。

首先,右击CoffeeQuest组,创建一个名为Factories的新组。接下来,在Factories组上点击右键,选择New File....。选择iOS ▸ Swift文件,然后点击下一步。把它叫做AnnotationFactory.swift,然后点击创建。你的文件夹结构应该类似于下面的样子。

最后,将AnnotationFactory.swift的内容替换为以下内容。

这看起来应该很熟悉(如果你读过前面的章节!)。这是在前一章中添加的代码,你为给定的咖啡店创建了BusinessMapViewModel。

这是你的第一个工厂! 当你采用工厂模式时,常常会感觉到你在剔除代码,就像你在这里一样。你的应用程序中的任何其他组件如果想从咖啡店模型中创建一个BusinessMapViewModel,现在就可以这么做了。

这是一个例子,说明工厂不能关闭进行修改,因为你需要添加和删除案例来制作不同的对象。

就像你在视图控制器中做的那样,你要切换到评级来决定使用哪张图片。

打开ViewController.swift,在//MARK下面添加以下属性。属性。

public let annotationFactory = AnnotationFactory()

最后,用下面的代码替换addAnnotations()。

是时候让你的视图控制器真正地使用这个工厂了! 该工厂为Yelp搜索中返回的每个企业创建一个businessMapViewModel。

构建并运行,以验证一切都像以前一样工作。

关键点

你在本章中了解了工厂模式。以下是其要点。

你又一次对视图控制器进行了瘦身。你的应用在视觉上没有什么变化,但实现工厂可以在项目不可避免地扩大时方便地进行修改。

你可能已经注意到,你的工厂只能从Yelp API中获取YLPBusiness。如果你想换成不同的服务,比如Google Places,会怎么样?重写你的代码将是一个好主意,这样你就可以接受任何第三方的类,并将其转换为一个更通用的Business类型。你将在下一章中使用适配器模式来完成这个任务。


上一章 目录 下一章