9
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

単純でないイニシャライザにはファクトリを

Last updated at Posted at 2023-11-04

前回に引き続き、Modelの設計についての勉強として「ドメイン駆動設計入門」を読み進めています。サンプルコードはC#で書かれていますが、iOSを勉強している人にもオススメの一冊です。

今回は9章ファクトリについての内容をベースに、Swiftのコードを使って紹介します。

イニシャライザは単純に

イニシャライザといえば、インスタンスの初期化の役目を担い、プロパティに初期値を代入する関数です。しかし、その初期化の処理が単純でなくなる場合には、ファクトリを用いて生成処理をカプセル化しましょう。
とはいえ単に「単純でないイニシャライザ」と言っても、基準が分かりづらいですよね。
「ドメイン駆動設計入門」では、その指標を以下のように示しています。

イニシャライザ内で他のオブジェクトを生成するかどうか

それでは、例を見てみましょう。

よくない例

例えば、ToDoアプリのドメインモデルとして、以下のようなModelがあるとします。

struct ToDo {
    private let id: ToDoID
    private(set) var title: ToDoTitle
    
    init(id: ToDoID, title: ToDoTitle) {
        self.id = id
        self.title = title
    }
    
    mutating func changeTitle(_ title: ToDoTitle) {
        self.title = title
    }
}

ここで、ToDoを新規作成する際に、IDを渡さなくても、Model側で新しいIDを生成する仕組みを作りたいと思いました。
真っ先に頭に浮かぶのは、引数にIDが不要なイニシャライザを、別で定義することでしょう。

struct ToDo {
    private let id: ToDoID
    private(set) var title: ToDoTitle
   
+   init(title: ToDoTitle) {
+       self.id = ToDoID(UUID().uuidString)
+       self.title = title
+   }
+  
    init(id: ToDoID, title: ToDoTitle) {
        self.id = id
        self.title = title
    }
    
    mutating func changeTitle(_ title: ToDoTitle) {
        self.title = title
    }
}

しかし、このイニシャライザは、ToDoIDの生成という単純ではないロジックを含んでしまっています。

ファクトリを用いた例

新たなイニシャライザを作るのではなく、ファクトリでIDを生成するようにします。

struct ToDoFactory {
    func create(title: ToDoTitle) -> ToDo {
        let id = ToDoID(UUID().uuidString)
        return ToDo(id: id, title: title)
    }
}

ToDoの新規作成は、ファクトリを使って行います。

let toDoFactory = ToDoFactory()
let toDo = toDoFactory.create(title: ToDoTitle("買い物に行く"))

これによって、イニシャライザに余計なロジックを持たさずに済みます。
この例では簡単のためにUUIDでIDを生成していますが、リポジトリを呼び出してIDの生成を行うといった処理も考えられます。

メソッドをファクトリの代わりにする例

そうは言っても、わざわざFactoryを作るほど大したことはしてないんだよな... ということもあるでしょう。その場合は、このようにstaticな関数を定義して同等のことを行うのも良さそうです。

struct ToDo {
    private let id: ToDoID
    private(set) var title: ToDoTitle
    
+   static func create(title: ToDoTitle) -> ToDo {
+       let id = ToDoID(UUID().uuidString)
+       return ToDo(id: id, title: title)
+   }
+   
    init(id: ToDoID, title: ToDoTitle) {
        self.id = id
        self.title = title
    }
    
    mutating func changeTitle(_ title: ToDoTitle) {
        self.title = title
    }
}
let todo = ToDo.create(title: ToDoTitle("買い物に行く"))

まとめ

ファクトリは、インスタンス生成の処理の複雑さを代わりに引き受けてくれます。
イニシャライザを記述する時には、複雑な処理を書かないように注意し、必要であればファクトリを定義しましょう。

参考

9
8
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
9
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?