LoginSignup
0
1

More than 1 year has passed since last update.

Factory Method パターンについてまとめてみた【Swiftでデザインパターン攻略 #1】

Posted at

はじめに

本記事では、GoFの23種類のデザインパターンの1つでもある、FactoryMethodパターンについて書いてみました。

FactoryMethodパターンとは

概要

「インスタンスの生成をサブクラスに実行させ、柔軟にインスタンス生成を行うためのパターン」のことです。
インスタンスを生成する側は、インスタンスについて直接意識しなくても、利用することができます。(Protocolを介しているため)

image.png
Wikipediaより

このパターンの進化前(?)のパターンで、Factoryパターン(SimpleFactory)というのがあります。
Factoryパターンは、1つのファクトリの中で、オブジェクトの種類の選択を動的に行うことが特徴です。

それに対し、FactoryMethodパターンでは、生成するオブジェクトごとに、Factoryクラスを用意することで、コードの冗長化や柔軟性を高めていることが特徴です。

SwiftにおけるFactoryMethodパターン

個人的な意見として、Swiftはenum型が強すぎて、Factoryパターンのほうが使用頻度が高い気がします。
Factoryパターンについては、下記をご覧ください。

実装してみた

今回のケースは、
従業員が職種別に存在する会社がある。
その会社の社員を職種で判断し、仕事(Task)を実行させたいと思います。

import UIKit

// MARK: Product(インスタンス化される側)のプロトコル
protocol Employee: AnyObject {
    var name: String { get set }
    var department: String { get }
    func executeTask()
}

// MARK: Creator(インスタンス化する側)のプロトコル
protocol Factory: AnyObject {
    func create(name: String) -> Employee
    func createEmployee(name: String) -> Employee
    func registerEmployee(_ employee: Employee)
}

// MARK: Productを実装した具象クラス
class Developer: Employee {
    var name: String
    var department: String {
        return "開発部"
    }

    init(name: String) {
        self.name = name
    }

    func executeTask() {
        print("\(department)\(name)は、コーディングを行います。")
    }
}

// MARK: Creatorを実装した具象クラス
class DeveloperFactory: Factory {
    var employeeList: [Employee] = []

    func create(name: String) -> Employee {
        let employee = createEmployee(name: name)
        registerEmployee(employee)
        return employee
    }

    func createEmployee(name: String) -> Employee {
        return Developer(name: name)
    }

    func registerEmployee(_ employee: Employee) {
        employeeList.append(employee)
    }
}

// MARK: 実行
let factory = DeveloperFactory()
let emp1 = factory.create(name: "山田")
emp1.executeTask()    // 開発部の山田は、コーディングを行います。

let emp2 = factory.create(name: "田中")
emp2.executeTask()    // 開発部の田中は、コーディングを行います。

冒頭でも述べたように、生成するインスタンスごとに、Factoryクラスを追加するのが特徴であるため、もし営業部を追加したいということであればこんな感じで追加します。

class SalesPerson: Employee {

    var name: String
    var department: String {
        return "営業部"
    }

    init(name: String) {
        self.name = name
    }

    func executeTask() {
        print("\(department)\(name)は、得意先への訪問を行います。")
    }
}

class SalesPersonFactory: Factory {
    var employeeList: [Employee] = []

    func create(name: String) -> Employee {
        let employee = createEmployee(name: name)
        registerEmployee(employee)
        return employee
    }

    func createEmployee(name: String) -> Employee {
        return SalesPerson(name: name)
    }

    func registerEmployee(_ employee: Employee) {
        employeeList.append(employee)
    }
}

// MARK: 実行
let salesFactory = SalesPersonFactory()
let emp3 = salesFactory.create(name: "佐藤")
emp3.executeTask()

以上!

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1