2
すべての主要なOOP機能を失うことなく、OOPで不変性を本当に使用できますか?
私のプログラムでオブジェクトを不変にすることの利点を理解しています。アプリケーションの良い設計について本当に深く考えているとき、私は多くの場合、オブジェクトの多くが不変であることに自然に到達します。多くの場合、すべてのオブジェクトを不変にしたいところになります。 この質問は同じ考えを扱っていますが、不変性に対する優れたアプローチと、それを実際に使用するタイミングを示唆する答えはありません。いくつかの良い不変のデザインパターンがありますか?一般的な考え方は、「オブジェクトを変更する必要が絶対にない限り、オブジェクトを不変にする」ことであるように見えますが、実際には役に立ちません。 私の経験では、不変性はコードをますます機能的なパラダイムに追い込み、この進行は常に起こります。 リスト、マップなどの永続的な(機能的な意味での)データ構造が必要になります。 相互参照(たとえば、子が親を参照している間、子を参照しているツリーノード)で作業することは非常に不便です。 継承は意味をなさないために停止し、代わりに構成を使用し始めます。 カプセル化のようなOOPの基本的な考え方全体がバラバラになり始め、私のオブジェクトは関数のように見え始めます。 この時点で、私は実際にはOOPパラダイムの何も使用しておらず、純粋に機能的な言語に切り替えることができます。したがって、私の質問:良い不変のOOP設計への一貫したアプローチがありますか、または不変のアイデアを最大限に活用すると、常にOOPの世界から何も必要としない関数型言語でプログラミングすることになりますか?OOPがバラバラにならないように、どのクラスを不変にし、どのクラスを不変にするかを決定するための良いガイドラインはありますか? 便宜上、例を示します。さんが持ってみましょうChessBoard不変のチェスの駒の不変なコレクションとして(抽象クラスを拡張しますPiece)。OOPの観点から見ると、ピースはボード上の位置から有効な動きを生成する役割を果たします。しかし、動きを生成するには、ピースがそのボードへの参照を必要とする一方で、ボードはそのピースへの参照を必要とします。さて、あなたのOOP言語に応じてこれらの不変の相互参照を作成するためのいくつかのトリックがありますが、それらは管理するのが苦痛で、ボードを参照する部分を持たない方が良いです。しかし、ボードの状態がわからないため、ピースは動きを生成できません。すると、ピースはピースタイプとその位置を保持する単なるデータ構造になります。その後、ポリモーフィック関数を使用して、あらゆる種類のピースの動きを生成できます。これは関数型プログラミングでは完全に達成できますが、ランタイム型チェックやその他の不適切なOOPプラクティスがないOOPではほとんど不可能です...