Swiftでデザインパターン ファクトリーパターン


ファクトリーパターン

  • オブジェクトの生成する処理をする専門のクラスを用意し、そこ(ファクトリー)に生成を任せてしまうもの
  • オブジェクトの生成にはパラメーターなどを指定する場合があるが、そこが複雑だと、いろんな場所で使い回すときにミスをしたり、面倒になるので、その問題を解決できる

import UIKit
/*
 記事を表示
 */
class ArticleViewController: UIViewController {

    // オブジェクト生成時にセットする想定
    var articleId: Int!

    func fetchArticleContentById() -> String {
        // ここでサーバーから記事IDから本文を取得する想定
        let content = "記事idが \(String(articleId)) の内容"
        return content
    }
}

問題点

  • 下記の通り、利用する際に、articleIdをセットする必要がある
  • このclassを作成したのが、自分だったら良いが、同僚のプログラマが作成していた場合、使い方を知る必要がある

// 例えば上記のようなViewContollerの場合、生成する際に、articleIdをセットする必要がある
let vc = ArticleViewController()
vc.articleId = 1
print(vc.fetchArticleContentById())
  • articleIdを忘れた場合(このclassの使い方)、下記の通りエラーになる場合がある

// ここでarticleIdを指定するのを忘れた場合はエラー
let vc2 = ArticleViewController()
print(vc2.fetchArticleContentById()) 
// Fatal error: Unexpectedly found nil while unwrapping an Optional value

解決法(ファクトリーパターンを利用する)

  • 生成を一任するFactoryクラスを実装する
  • init時に、必要なパラメーターを指定できるようにする

// 生成を一任するクラスを作成する
class ArticleViewControllerFactory {
    private let articleId: Int

    init(articleId: Int) {
        self.articleId = articleId
    }

    func makeArticleViewController() -> ArticleViewController {
        let vc = ArticleViewController()
        vc.articleId = self.articleId
        return vc
    }
}
  • 利用する際は、このようになる
  • 生成時に必要なパラメーターの指定忘れや、手順が違うなどのミスや複雑性を排除されているのがおわかりいただけるだろうか
let factory = ArticleViewControllerFactory(articleId: 1)
let vc3: ArticleViewController = factory.makeArticleViewController()
vc3.fetchArticleContentById() // 記事idが 2 の内容

以上