Prototype

デザインパターンとはオブジェクト思考開発における先人たちが作り上げてきた便利な設計図です。

Gang of Four通称Gofが1994年に出版した『オブジェクト指向における再利用のためのデザインパターン』の中で23個の設計図が紹介されています。

Note

デザインパターンのサンプルコードはSwift4でまとめます

プロトタイプパターンとは?

Prototypeパターンは1つ作成した原型を複製するパターンです。

複製はインスタンスを生成するのではなく、既存のインスタンスのコピーを生成するためコストが低くなります。

サンプルコード

サンプルコードでは泥だんごを例にコードを作ってみました。子供の頃に一生懸命作っていた泥団子ですが、ピカピカの泥だんごを作るのはすごく時間がかかります。

泥だんごクラス

mapの中に生成コストの高いオブジェクトをregisterメソッド保存しておき、copyメソッドで保存されているオブジェクトを返します。

class MudBallFactory{
    var map:[String: Clonable] = [:]
    
    func register(key: String,mudBall: Mud) {
        map[key] = mudBall
    }
    func copy(key: String) -> Clonable {
        return map[key]!
    }
}

Protocol

泥だんごの元、つまり泥に対してClonableプロトコルを準拠させます。

protocol Clonable {
    func createClone() -> Clonable
}

泥クラス

泥だんごを固めるメソッドconsolidateとぴかぴかに磨くメソッドconsolidateの中の処理は簡単な処理に割愛していますが処理が重く大変なものであると考えてください。

Clonableに準拠しているため、加工した泥を複製するcreateCloneメソッドを保持しています

class Mud: Clonable {
    var name = "泥"

    func createClone() -> Clonable {
        let copy = Mud()
        copy.name = self.name
        return copy
    }
    
    func consolidate(){
        name = "\(name)団子"
    }
    
    func polish(){
        name = "ピカピカの\(name)"
    }
}

呼び出し元

//ぴかぴかの泥団子を1つ作る
let mudBall = Mud()
mudBall.consolidate()
mudBall.polish()
print(mudBall.name)

//コピーを生成するためにファクトリーに登録
let factory = MudBallFactory()
factory.register(key: "mudBall", mudBall: mudBall)

//コピー作成
let copy = factory.copy(key: "mudBall").createClone() as! Mud
print(copy.name)

コンソール

ピカピカの泥団子
ピカピカの泥団子

コード一覧

import UIKit

class MudBallFactory{
    var map:[String: Clonable] = [:]
    
    func register(key: String,mudBall: Mud) {
        map[key] = mudBall
    }
    func copy(key: String) -> Clonable {
        return map[key]!
    }
}

protocol Clonable {
    func createClone() -> Clonable
}

class Mud: Clonable {
    var name = "泥"

    func createClone() -> Clonable {
        let copy = Mud()
        copy.name = self.name
        return copy
    }
    
    func consolidate(){
        name = "\(name)団子"
    }
    
    func polish(){
        name = "ピカピカの\(name)"
    }
}

//ぴかぴかの泥団子を1つ作る
let mudBall = Mud()
mudBall.consolidate()
mudBall.polish()
print(mudBall.name)

//コピーを生成するためにファクトリーに登録
let factory = MudBallFactory()
factory.register(key: "mudBall", mudBall: mudBall)

//コピー作成
let copy = factory.copy(key: "mudBall").createClone() as! Mud
print(copy.name)

参考文献

Prototype パターン

Swiftで学ぶデザインパターン5 (Prototype パターン)