読者です 読者をやめる 読者になる 読者になる

DDD における不要な getter/setter を実装するべきではないという件についての挫折と感想

DDD

別にDDDにかぎらず、
不要な getter/setter を実装しない方がいいというのはその通りなんだけど、
DBに紐づくモデルの getter に関してはそれができないケースがある。

利用するORMによって、DBに紐づくモデルに規約が定められている場合は無理。
例えば、クラス内のプロパティは public じゃないとダメとか。

このようなライブラリ、フレームワークに依存したモデル実装を回避するために
ORMを利用せずに、手動でSQLを発行したり、クエリビルダを利用しても、
結局モデル内の name, score という「テーブルに反映させたいデータ」を取得する必要があるので、
getter は必要になってしまう。

リフレクションで取得する方法はあるが、
言語によっては実行速度がボトルネックになったり、
人によっては private なフィールドを触るというのに抵抗があったり、
なかなか綺麗に解決できなかったりする。

そもそも、リフレクション利用するなら getter が必要ってことじゃないのか? って思うこともあるけど、
不要かどうかってのはドメインレイヤ内で不要かどうかって話だから、
DBに近いインフラレイヤとかで必要になっても、
それをモデルが実装する必要性って無いと思うんだよね。

Java のORMである hibernate, mybatis とかは
こういった問題を解決してくれているのかな・・・。
使ったことないから分からないけど、
XMLとかでマッピングすると、上手くやってくれる感じがする。

自分は PHP, Ruby とかがメインだったから、
rails ライクな規約重視のフレームワークを利用することが多く、
「不要な getter を実装しない方がいい」というルールを守れずにいた。

で、結局自分はフレームワークやライブラリの規約に従っている。
手動でマッピングする場合は getter を実装している。
といっても、手動でマッピングするのってほぼプライベートな実装だけなんだけど・・・。

これはもう綺麗な解決方法を諦めた結果で、
リフレクションとか利用するよりはいいかなと・・・。
いっても、getter って副作用ないし・・・。
とか思ってる。

手動でマッピングする場合に限って、
最近は getter を用意せずに、DBに必要なプロパティを持つハッシュを出力する関数を実装したりもする。
擬似的なコードだけど、以下のイメージ。

func  toHash() {
    return {
        name: this.name,
        score: this.score,
    }
}

DBに近いORMとかクエリビルダって、
データに関心があるだけだから、
テーブルのカラムに対応するデータが取得できればいい。

ということは、getterで取得する必要はないのでは?
getter を用意すると、getName(), getScore() とかになって、それがドメインレイヤでノイズになる気がするから、
もうハッシュとか出力すればいーのでは?
ドメインモデルにだって toString() 的なのは実装するでしょ。
だったら、toHash() あってもいいよね。
という発想。

データの整合性というか、妥当性はモデル自体が担保してくれるはずだから、
そこから出力されるハッシュは安全なはず。
そして、わざわざ toHashForDB() のように「DB」とか特定のアーキテクチャの名前とか付けなくていいはず。
クラス内にあるデータだから、別にアーキテクチャとか関係ない。
利用する側が選んで使えばいい。

で、ORMとかクエリビルダは、テーブルのカラムを意識するから、
ハッシュのキーを意識してもいいよねって思う。

もちろん、クエリビルダを利用する側からすると、
ハッシュのキーを確認するより getter あった方がいいんだけど、
そうするとドメインレイヤでノイズになる気がするから・・・。

ということで、どっちを取るかの問題かなと。

getter でやったらノイズになるかとか、
ハッシュでやったらキーを意識しないといけないから面倒なのかとか、
実際にやった感想でいうと、どっちもどっちなきがする。
明確に「こっちがよかった」というのはない。

そして、今ではこういった問題を解決できる言語なり、ライブラリなり、フレームワークなりを選定する必要があると思ってる。

言語とかライブラリによって設計思想は変わると思うので、
そりゃ全部が全部できるってわけじゃない。

で、そんなこと分かっているけど、
できた方が幸せじゃんって、
チャレンジしてみた結果、ダメでしたというお話。

無理なもんは無理なので、選定した技術の上に乗せられるものでやっていきましょう。