この記事シリーズは、iOS/Swiftエンジニアである執筆者個人が、
ごく普通のiOSアプリ開発でよくある状況や
Swiftのコアライブラリやフレームワークで使われているパターンに
着目してデザインパターンを学び直してみた記録です。
関連記事一覧
[iOS/Swift] アプリ開発の実務的アプローチで学ぶデザインパターン
Prototypeパターン概要
- 生成済みのインスタンスを元に別のインスタンスを作り出すパターンです。
- GoFのデザインパターンでは生成に関するパターンに分類されます。
使い所
- Swiftのclassは参照型なので、classAのインスタンスを変数Xから変数Yに代入すると、いずれも同じインスタンスへの参照になってしまいます。大抵の場合は、classAの新しいインスタンスを生成して変数Yに格納すれば済む話だったりしますが…
- classAに、「変数Xのプロパティ値をそのまま変数Yに引き継ぎたい」という場面が多い、という特性がある場合にはPrototypeパターンが使えるかもしれません。
- 具体的な例としては、Realmデータベースにおけるオブジェクトコピーです。(参考)Realmオブジェクトのクローン
サンプルコード
Swiftバージョンは 5.1 です。
class Person {
var firstName: String
var familyName: String
init(firstName: String = "", familyName: String) {
self.firstName = firstName
self.familyName = familyName
}
// 自分自身の値をセットして新しいインスタンスを生成する
func clone() -> Person {
return Person(firstName: self.firstName, familyName: self.familyName)
}
}
let prototype = Person(familyName: "Yamada")
let person1 = prototype.clone()
person1.firstName = "Taro"
print("firstName: \(person1.firstName), familyName: \(person1.familyName)")
// firstName: Taro, familyName: Yamada
let person2 = prototype.clone()
person2.firstName = "Hanako"
print("firstName: \(person1.firstName), familyName: \(person1.familyName)")
// firstName: Taro, familyName: Yamada
print("firstName: \(person2.firstName), familyName: \(person2.familyName)")
// firstName: Hanako, familyName: Yamada