getter/setterがなぜマズいか
getterとsetterは、クラスをみせかけのデータ構造に変える。で、そのデータ構造は独自のAPIをもつことになる。XとYの属性を持てば、getXとsetX, getYとsetYというように。で、これを使う人はこれらを使って業務をどう組み立てなくてはならないかを学ぶ必要がある。
まぁ、これはまだ良いのだが、データモデリングの観点からいうと、問題を先送りできちゃうことがよりマズいのだ。「Xが変わる可能性があるので、Xをセットできる必要があります。このオブジェクトをインスタンス化した後で変更する必要があるかもしれません。」というように。Xをセットするとして、その変更が業務上何を意味するのか? 全く考えていない。「Xがいつ変更されるのか、またどのような条件下で変更するのかを決めるのは、コードの他の部分に任せるつもりです。」
より具体的な例をあげよう。従業員クラスがあって、給料という属性をもっているとしよう。「給料は変わる可能性があります。なので、従業員クラスに給料のsetterを用意します。」
従業員の給料を変更するとはどういう意味? 給料を入力したときに間違えたのでその間違いを訂正する必要がある? 0は除外する? 君がこの従業員に対してやることは、給料の間違いの訂正ということのようだ。
従業員が昇給したら? これはまた違った事象のようだ。降級することもあれば、業績の悪化で「一律10%給料カット」ということもあるかもしれない。これらは「間違いの訂正」ではないようだ。
給料について業務上どういう変化があるかを考えずに「3ドルに設定する」というのは、設計の先送りだ。従業員の給料を直接読み書きしたり、好きなように設定したりできるのは業務としてはなんの意味もない。「この人は昇給した」「私は間違って入力したので訂正する」などが業務上意味を持つ従業員の給料へのアクセスだ。
https://gyazo.com/de58f1a9169991648d46ebaecbf72c6b
これをもとに実際のモデルを書いてみると以下のようになる。
https://gyazo.com/2ab6e6650e33ada0eb978c5980c5d8e7
対象のレイヤー、クラスの分類を明らかにせずに、getter/setterが悪かどうか議論するのは不毛なことである。