ゲッターなしでは良いコードを書くことはできません。
理由は、ゲッターがカプセル化を壊さないからではありません。それは、ゲッターが、操作するデータを使用してメソッドを配置するOOPをたどらないように人々を誘惑しないからではありません。彼らはします。いいえ、境界のためにゲッターが必要です。
メソッドの移動を妨げ、データの移動を余儀なくされる境界にぶつかると、カプセル化とメソッドが作用するデータを一緒に保持するというアイデアは単に機能しません。
本当に簡単です。境界がないときにゲッターを使用すると、実際のオブジェクトがなくなります。すべてが手続き型になり始めます。これは以前と同じように機能します。
真のOOPは、どこにでも広めることができるものではありません。これらの境界内でのみ機能します。
これらの境界線は非常に薄くありません。それらにはコードがあります。そのコードをOOPにすることはできません。機能することもできません。このコードは、厳しい現実に対処できるように、理想を取り除いたものではありません。
マイケル・フェッターズは、オレンジの部分を一緒に保持する白い結合組織にちなんで、このコードを筋膜と呼びました。
これはそれについて考える素晴らしい方法です。同じコードベースに両方の種類のコードを入れても大丈夫な理由を説明しています。この観点がなければ、多くの新しいプログラマーは理想に固執し、最初の境界に達したときに心を砕き、これらの理想をあきらめます。
理想は適切な場所でのみ機能します。どこでも動作しないという理由だけで、あきらめないでください。動作する場所で使用します。その場所は、筋膜が保護するジューシーな部分です。
境界の簡単な例はコレクションです。これは何かを保持しており、それが何であるかを知りません。コレクションデザイナは、保持するオブジェクトの動作機能を、保持するオブジェクトが分からないときに、どのようにしてコレクションに移動できますか?できません。あなたは境界に立ち向かっています。これが、コレクションにゲッターがある理由です。
知っていれば、その動作を移動でき、状態の移動を回避できます。知っているときは、すべきです。いつもわからない。
一部の人々は、これを実際的なものと呼んでいます。そしてそうです。しかし、なぜ実用的でなければならないのかを知ってうれしいです。
あなたはセマンティックな議論を聞きたくないと言い、どこにでも「賢明なゲッター」を置くことを主張しているようです。このアイデアに挑戦することを求めています。私はあなたがそれを組み立てた方法に問題があるという考えを示すことができると思います。しかし、私はそこにいたので、あなたがどこから来たのかも知っていると思います。
どこでもゲッターが必要な場合は、Pythonを見てください。プライベートキーワードはありません。しかし、PythonはOOPをうまく機能させます。どうやって?セマンティックトリックを使用します。彼らは、先頭に下線を付けて個人的なものを意味します。あなたがそうすることに責任を負うならば、あなたはそれから読むことさえ許されます。「私たちはみんな大人です」と彼らはよく言います。
それでは、JavaとC#のすべてにゲッターを置くことと、それとの違いは何ですか?申し訳ありませんが、セマンティクスです。Pythonは、従業員専用のドアの後ろで突っついていることを明確に示しています。すべてにゲッターを平手打ちすると、そのシグナルを失います。リフレクションを使用すると、とにかくプライベートを取り除いても、セマンティックシグナルを失うことはありません。ここで行われる構造的な議論はありません。
したがって、残されているのは、「従業員のみ」のサインをどこに掛けるかを決める仕事です。プライベートと見なすべきものは何ですか?それを「賢明なゲッター」と呼びます。私が言ったように、ゲッターの最良の正当化は、私たちを理想から遠ざける境界です。それはすべてのゲッターをもたらすべきではありません。ゲッターが発生する場合は、動作を保護できるジューシーなビットにさらに移動することを検討する必要があります。
この分離はいくつかの用語を生み出しました。データ転送オブジェクトまたはDTOは、動作を保持しません。唯一のメソッドは、ゲッターとセッター、時にはコンストラクターです。この名前は本当のオブジェクトではないため、残念です。ゲッターとセッターは、実際にはブレークポイントを設定する場所を提供するコードをデバッグするだけです。その必要がなければ、パブリックフィールドの山になります。C ++では、構造体と呼ばれていました。C ++クラスとの唯一の違いは、デフォルトに設定されていたことです。
DTOは境界壁を越えて投げることができ、他のメソッドを安全で素晴らしいジューシーな動作オブジェクトに保持できるので便利です。真のオブジェクト。違反するゲッターがないため、カプセル化されます。私のビヘイビアオブジェクトは、パラメータオブジェクトとして使用することでDTOを食べる場合があります。共有の可変状態を防ぐために防御的コピーを作成しなければならないこともあります。境界内のジューシーな部分の内側に可変DTOを分散させません。それらをカプセル化します。隠します。そして、ついに新しい境界にぶつかったとき、私は新しいDTOをスピンアップし、それを壁に投げて、他の誰かの問題にします。
しかし、アイデンティティを表現するゲッターを提供する必要があります。おめでとうございます、境界が見つかりました。エンティティには、参照を超えるアイデンティティがあります。つまり、メモリアドレスを超えています。そのため、どこかに保存する必要があります。そして、何かがそのアイデンティティによってこのものを参照できなければなりません。アイデンティティを表現するゲッターは完全に合理的です。そのゲッターを使用して、エンティティがそれ自体で行うことができる決定を行うコードの山はそうではありません。
結局のところ、間違っているのはゲッターの存在ではありません。パブリックフィールドよりもはるかに優れています。悪いのは、そうでないときにあなたがオブジェクト指向であるふりをするのに使われるときです。ゲッターは良いです。オブジェクト指向であることは良いことです。ゲッターはオブジェクト指向ではありません。ゲッターを使用して、オブジェクト指向の安全な場所を切り分けます。