首页 iOS.& Swift Books 教程设计模式

11
工厂模式 杰伊突发撰写

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

  1. 工厂 creates objects.
  2. 产品 是创建的对象。

从技术上讲,这种模式的多种“味道”,包括简单的工厂,抽象工厂等。但是,这些共享共同目标:在自己的构造中隔离对象创建逻辑。

在本章中,您将在上一章的项目中添加到上一章, 咖啡任务,了解一个 简单工厂。它创建了通用类型或协议的对象,而工厂类型本身是已知的并由消费者直接使用。

你什么时候应该用它?

每当您要分开产品创建逻辑时,请使用工厂模式,而不是将消费者直接创建产品。

当您拥有一组相关产品时,工厂非常有用,例如多态子类或实现相同协议的多个对象。例如,您可以使用工厂检查网络响应并将其转换为混凝土模型亚型。

当您拥有单一产品类型时,工厂也很有用,但它需要提供依赖项或信息来创建它。例如,您可以使用工厂创建“求职者响应”电子邮件:工厂可以根据候选人是否被接受,拒绝或需要进行接受采访来创建电子邮件详情。

操场例子

打开 中级agepattern.xcWorkspace. 在里面 起动机 目录,或从最后一章中从您自己的游乐场工作区继续,然后打开 工厂 页。如上所述,您将创建一个工厂来生成求职者响应电子邮件。之后添加以下内容 代码示例:

import Foundation

public struct JobApplicant {
  public let name: String
  public let email: String
  public var status: Status
  
  public enum Status {
    case new
    case interview
    case hired
    case rejected
  }
}

public struct Email {
  public let subject: String
  public let messageBody: String
  public let recipientEmail: String
  public let senderEmail: String
}
// 1
public struct EmailFactory {
  
  // 2
  public let senderEmail: String
  
  // 3
  public func createEmail(to recipient: JobApplicant) -> Email {
    let subject: String
    let messageBody: String

    switch recipient.status {
    case .new:
      subject = "We Received Your Application"
      messageBody = 
        "Thanks for applying for a job here! " +
        "You should hear from us in 17-42 business days."

    case .interview:
      subject = "We Want to Interview You"
      messageBody = 
        "Thanks for your resume, \(recipient.name)! " +
        "Can you come in for an interview in 30 minutes?"

    case .hired:
      subject = "We Want to Hire You"
      messageBody = 
        "Congratulations, \(recipient.name)! " +
        "We liked your code, and you smelled nice. " +
        "We want to offer you a position! Cha-ching! $$$"

    case .rejected:
      subject = "Thanks for Your Application"
      messageBody = 
        "Thank you for applying, \(recipient.name)! " +
        "We have decided to move forward " +
        "with other candidates. " +
        "Please remember to wear pants next time!"
    }

    return Email(subject: subject,
                 messageBody: messageBody,
                 recipientEmail: recipient.email,
                 senderEmail: senderEmail)
  }
}
var jackson = JobApplicant(name: "Jackson Smith",
                           email: "[email protected]",
                           status: .new)

let emailFactory = 
  EmailFactory(senderEmail: "[email protected]")

// New
print(emailFactory.createEmail(to: jackson), "\n")

// Interview
jackson.status = .interview
print(emailFactory.createEmail(to: jackson), "\n")

// Hired
jackson.status = .hired
print(emailFactory.createEmail(to: jackson), "\n")

你应该小心吗?

并非所有多态性物体都需要工厂。如果您的对象非常简单,则可以始终将创建逻辑直接放在消费者中,例如视图控制器本身。

教程项目

您将继续从上一章继续咖啡符。如果您跳过上一章,或者您想要新的开始,请打开 发现者 并导航到您下载本章的资源的位置。然后,开放 起动机 \ CoffeeQuest \ CoffectQuest.xcWorkspace (不是 .xcodeproj.)在Xcode中。

import UIKit
import MapKit
import YelpAPI

public class AnnotationFactory {
  
  public func createBusinessMapViewModel(
    for business: YLPBusiness) -> BusinessMapViewModel? {
    
    guard 
      let yelpCoordinate = business.location.coordinate else {
        return nil
    }

    let coordinate = 
      CLLocationCoordinate2D(
        latitude: yelpCoordinate.latitude,
        longitude: yelpCoordinate.longitude)

    let name = business.name
    let rating = business.rating
    let image: UIImage
    switch rating {
    case 3.0..<3.5:
      image = UIImage(named: "bad")!
    case 3.5..<4.0:
      image = UIImage(named: "meh")!
    case 4.0..<4.75:
      image = UIImage(named: "good")!
    case 4.75...5.0:
      image = UIImage(named: "great")!
    default:
      image = UIImage(named: "bad")!
    }
    return BusinessMapViewModel(coordinate: coordinate,
                                image: image,
                                name: name,
                                rating: rating)
  }
}
switch rating {
case 0.0..<3.0:
  image = UIImage(named: "terrible")!
case 3.0..<3.5:
  image = UIImage(named: "bad")!
case 3.5..<4.0:
  image = UIImage(named: "meh")!
case 4.0..<4.75:
  image = UIImage(named: "good")!
case 4.75...5.0:
  image = UIImage(named: "great")!
default:
  image = UIImage(named: "bad")!
}
public let annotationFactory = AnnotationFactory()
private func addAnnotations() {    
  for business in businesses {
    guard let viewModel = 
      annotationFactory.createBusinessMapViewModel(
        for: business) else {
          continue
    }
    mapView.addAnnotation(viewModel)
  }
}

关键点

您在本章中了解了工厂模式。以下是其关键点:

有一个技术问题?想报告一个错误吗? 您可以向官方书籍论坛中的书籍作者提出问题和报告错误 这里.

有反馈分享在线阅读体验吗? 如果您有关于UI,UX,突出显示或我们在线阅读器的其他功能的反馈,您可以将其发送到设计团队,其中表格如下所示:

© 2021 Razeware LLC

您可以免费读取,本章的部分显示为 混淆了 文本。解锁这本书,以及我们整个书籍和视频目录,带有Raywenderlich.com的专业订阅。

现在解锁

要突出或记笔记,您需要在订阅中拥有这本书或自行购买。