LoginSignup
7
2

More than 3 years have passed since last update.

【Scala】悩ましいインターフェース問題

Last updated at Posted at 2019-05-02

はじめに

ScalaでDDDやらクリーンアーキテクチャやらまじめに考えると、リポジトリやサービスのインターフェースの設計に色んな手段が考えられて悩ましいという話。

シンプルなインターフェース

ある意味でシンプルに環境依存も含めて宣言しちゃうパターン。


// 環境依存1 = DBSession
trait Repository[DBSession] {

  // 環境依存2 = Future
  def findOne(implicit session: DBSession): Future[Either[Throwable, A]]

}

DBSessionはインフラ層で決定されるとしても、なんだか「依存性逆転の原則」違反がチラチラしてる気がして気になります(違反はしてないとは思うけど)。
当然、環境が変化したらインターフェースも書き換えでしょう(FutureがTryになるとか)。

ただ必要な型が全部見えてるので実装時に楽っちゃ楽だったりします。

モナディックなインターフェース

環境依存は悪だ!Monadが使えるんだから環境は抽象化できるはずだ!


trait Repository[M[_]] {

  def findOne: M[Either[Throwable, A]]

}

2019年5月10日修正:実装しずらかったのでM[_]の宣言位置を変えました。

これが一番「クリーンアーキテクチャ」的で綺麗な宣言かと思います。
実装時にM[_]の型はKleisli[Future, DBSession, ?]のようになることでしょう。
このパターンの一番の問題は、アプリケーション層等での利用時にfor comprehension内で型揃えが頻発することです。

全部EitherTでくるんで、FutureじゃないやつはFuture.successfulでくるんで・・・TaskTryも?どうすんだこれ?

ExtensibleEffectsなインターフェス

モナディックなインターフェースの型合わせが面倒くさい!インターフェースが綺麗でも実装が汚いのは嫌じゃ!

・・・となった時に現れたのがEffことExtensibleEffectsです。


// ふたたび現れるDBSession ← どうにかする方法を模索中
trait Repository[DBSession] {

  type _sessionReader[DBSession] = Reader[DBSession, ?] |= R

 // Eff <- from atnos-org/eff
  def findOne[R: _sessionReader]: Eff[R, A]

}

また環境がチラチラしてますが、まあ戻り値には影響を及ぼさないので良しとしておいてください。
Eff自体の詳しい解説は下部の参考先を見てもらうとして、Effを用いた場合、モナディックなインターフェースと違い、Monadであることをキープしたまま実装時のfor comprehension内での面倒な型揃えを回避することができます。

ただし、インターフェース宣言時にcontext boundを明示したり、関数呼び出し時に型を明示したり、最終的な実行時にrunReaderやらrunEitherやらを必要分記述しなければいけません。・・・あれ?これ逆に面倒くさいんじゃ・・・

おわりに

それで、どれが良いのか結論は?

いや、だから悩んでるって話しでして・・・

  • 「シンプルなインターフェース」は自分的にはScalaである必要なくなっちゃうんで無し。
  • 「モナディックなインターフェース」は確かに見た目はよいし、クリーンアーキテクチャちっくな雰囲気ある。ただ実装は汚れがち。
  • 「ExtensibleEffectsなインターフェス」は実は後の手間よりもインターフェースが汚れやすいのが問題だったりするかも?(環境分、context boundが増える)for comprehensionはまじ綺麗になる。

「モナディックなインターフェース」と「ExtensibleEffectsなインターフェス」の2択かなぁ。

・・・もう気持ちの問題なのかもって気がしなくもない。

参考先

モナディックなインターフェース関連

ExtensibleEffectsなインターフェス関連

7
2
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
7
2