3️⃣

[読書メモ]オブジェクト設計スタイルガイド 6章5節 with TypeScript

2024/03/03に公開

オブジェクト設計スタイルガイドを読みながら、TypeScriptでやるならどうやるかを考えながら書きました。
要約的に読める内容になっていると思うので、サクッと3分ぐらいで読める記事となっています。
https://www.oreilly.co.jp/books/9784814400331/

6.5 システム境界を超えるクエリに対する抽象を定義する

以下の要素が揃っていることが大切。

  • サービスクラスの代わりにサービスインターフェースを使う
  • 実装の詳細に入り込まない

以下のように実装の詳細に入り込まないようにする。

NG

class FixerAPI {
  exchangeRateFor(from: Currency, to: Currency): ExchangeRate {
    httpClient = new HttpClient()

    res = httpClient.get(/**/)

    decoded = json_decode(res.body)

    rate = Number(decoded.rates)

    return ExchangeRate.from(from, to, rate)
  }
}

class CurrencyConverter {
  private fixerAPI: FixerAPI

  convert(money: Money, to: Currency) {
    rate = this.fixerAPI.exchangeRateFor(money.currency(), to)

    return money.convert(rate)
  }
}

以下のように、インターフェース、つまり抽象に依存することで、実装の詳細に入り込まないようにする。
メリットとしては、

  • テストがしやすくなる
  • 他の実装に簡単に切り替えられる

OK

interface ExchangeRateProvider {
  exchangeRateFor(from: Currency, to: Currency): ExchangeRate
}

class FixerAPI implements ExchangeRateProvider {
  exchangeRateFor(from: Currency, to: Currency): ExchangeRate {
    // ...
  }
}

class CurrencyConverter {
  private exchangeRateProvider: ExchangeRateProvider

  convert(money: Money, to: Currency) {
    rate = this.exchangeRateProvider.exchangeRateFor(money.currency(), to)

    return money.convert(rate)
  }
}

Discussion