🕊

[Swift] Entity

2022/12/12に公開約3,500字

前提

  • FrameworkEntity は DomainEntity を知っている
  • DomainEntity は FrameworkEntity を知らない
struct DomainEntity {
    let hoge: Int
    let moge: Int
}

struct FrameworkEntity {
    let hoge: Int
    let moge: Int
}

共通処理は以下とします。

let domainEntity = DomainEntity(hoge: 1, moge: 2)
let frameworkEntity = FrameworkEntity(hoge: 3, moge: 4)

DomainEntity -> FrameworkEntity の変換のパターン

(1) 既存の init を直接使用する

let frameworkEntity = FrameworkEntity(hoge: domainEntity.hoge, moge: domainEntity.moge)
  • メリット
    • シンプル
  • デメリット
    • 変数が多いと大変
    • テストしづらい

(2) FrameworkEntity に新たな init を定義する(引数:DomainEntity)

extension FrameworkEntity {
    init(domainEntity: DomainEntity) {
        hoge = domainEntity.hoge
        moge = domainEntity.moge
    }
}

let frameworkEntity = FrameworkEntity(domainEntity: domainEntity)

よさそう、テストもできそう、イニシャライズが増えてしまうのが懸念かもしてませんどこでも使われてしまう危険性がありそうです。
変数が増えても上手く表せそう、いろんな処理もできそう

  • メリット
    • テストしやすい
    • 変数が多い
  • デメリット
    • イニシャライズの方法が増えてしまう

こうもかけるが、変換時に処理を

extension FrameworkEntity {
    init(domainEntity: DomainEntity) {
        self.init(hoge: domainEntity.hoge, moge: domainEntity.moge)
    }
}

let frameworkEntity = FrameworkEntity(domainEntity: domainEntity)

(3) FrameworkEntity を変換する箇所で DomainEntity を private extension で変換する変数を定義する

private extension DomainEntity {
    var frameworkEntity: FrameworkEntity {
        FrameworkEntity(hoge: self.hoge, moge: self.moge)
    }
}

let frameworkEntity = domainEntity.frameworkEntity

→ ドメイン層はFramework層を知らないはず ❌

(4) FrameworkEntity を変換する箇所で DomainEntity を private extension で変換する関数を定義する

private extension DomainEntity {
    func convertToFrameworkEntity() -> FrameworkEntity {
        FrameworkEntity(hoge: self.hoge, moge: self.moge)
    }
}

let frameworkEntity = domainEntity.convertToFrameworkEntity()

→ ドメイン層はFramework層を知らないはず ❌

(5) FrameworkEntity を変換する箇所で DomainEntity に変換する関数を定義する

func convertToFrameworkEntity(from domainEntity: DomainEntity) -> FrameworkEntity {
    FrameworkEntity(hoge: domainEntity.hoge, moge: domainEntity.moge)
}

let frameworkEntity = convertToFrameworkEntity(from: domainEntity)

→ 悪くはないはず、テストもできそう、ただ、変数が増えると、大変そう。(1) と同じ ▲

FrameworkEntity -> DomainEntityの変換のパターン

(1) 普通に init する

let domainEntity = DomainEntity(hoge: frameworkEntity.hoge, moge: frameworkEntity.moge)

(2) DomainEntity を渡すイニシャライズを定義する

extension DomainEntity {
    init(frameworkEntity: FrameworkEntity) {
        hoge = frameworkEntity.hoge
        moge = frameworkEntity.moge
    }
}

let domainEntity = DomainEntity(frameworkEntity: frameworkEntity)

(3) FrameworkEntity を変換する箇所で DomainEntity を private extension で変換する変数を定義する

private extension FrameworkEntity {
    var domainEntity: DomainEntity {
        DomainEntity(hoge: self.hoge, moge: self.moge)
    }
}

let domainEntity = frameworkEntity.domainEntity

(4) FrameworkEntity を変換する箇所で DomainEntity を private extension で変換する関数を定義する

private extension FrameworkEntity {
    func convertToDomainEntity() -> DomainEntity {
        DomainEntity(hoge: self.hoge, moge: self.moge)
    }
}

let domainEntity = frameworkEntity.convertToDomainEntity()

(5) FrameworkEntity を変換する箇所で DomainEntity に変換する関数を定義する ← これがいい気がする

func convertToDomainEntity(from frameworkEntity: FrameworkEntity) -> DomainEntity {
    DomainEntity(hoge: frameworkEntity.hoge, moge: frameworkEntity.moge)
}

let domainEntity = convertToDomainEntity(from: frameworkEntity)
GitHubで編集を提案

Discussion

ログインするとコメントできます