1. ホーム
  2. oop

[解決済み] ミュータブルとイミュータブルのオブジェクト

2022-04-15 07:42:10

質問

ミュータブルオブジェクトとイミュータブルオブジェクトについて理解しようとしているところです。ミュータブルオブジェクトの使用は、多くの悪い評判がありますが(例えば、メソッドから文字列の配列を返すなど)、これによる悪影響が何なのか理解するのに苦労しています。ミュータブルオブジェクトを使用する際のベストプラクティスは何でしょうか?可能な限り避けるべきでしょうか?

どのように解決するのですか?

さて、これにはいくつかの側面があります。

  1. 参照同一性のないMutableオブジェクトは、奇妙なタイミングでバグを引き起こす可能性があります。 例えば Person ビーンに、値ベースの equals メソッドを使用します。

    Map<Person, String> map = ...
    Person p = new Person();
    map.put(p, "Hey, there!");
    
    p.setName("Daniel");
    map.get(p);       // => null
    
    

    Person インスタンスは、キーとして使われるとマップ内で "lost"されます。 hashCode と等号は、変更可能な値に基づいています。 これらの値はマップの外側で変更され、すべてのハッシュは時代遅れになってしまいます。 理論家はこの点を強調したがりますが、実際にはそれほど問題になるとは思えません。

  2. もうひとつの側面は、コードの論理的な合理性です。 これは定義が難しい用語で、読みやすさからフローまですべてを含んでいます。 一般的には、コードの一部を見て、それが何をしているのかを簡単に理解できる必要があります。 しかし、それ以上に重要なのは、そのコードが何をするものなのかを自分自身に納得させることができることです。 正しく . オブジェクトが異なるコード"ドメイン"で独立して変更できる場合、何がどこで、なぜかを追跡することが難しくなることがあります(" スプーキーアクション・アット・ア・ディスタンス ")です。 これは例えるのが難しい概念ですが、より大規模で複雑なアーキテクチャではよく直面することです。

  3. 最後に、ミュータブルオブジェクトは キラー は、同時並行の状況下で 別々のスレッドからミュータブルオブジェクトにアクセスするときは、必ずロッキングに対処しなければなりません。 これはスループットを低下させ、あなたのコードを 劇的に メンテナンスがより困難になります。 十分に複雑なシステムでは、この問題があまりにも大きくなり、(同時実行の専門家であっても)保守がほぼ不可能になります。

イミュータブルオブジェクト(特にイミュータブルコレクション)は、これらの問題をすべて回避することができます。 一度、その仕組みを理解すれば、あなたのコードは、読みやすく、保守しやすく、奇妙で予測不可能な方法で失敗する可能性の低いものに発展するでしょう。 イミュータブルオブジェクトはモックになりやすいだけでなく、コードパターンを強制しやすいので、テストがより簡単になります。 要するに、全体として良い習慣なのです。

とはいえ、私はこの件に熱心なわけではありません。 ある種の問題は、すべてをイミュータブルにするとうまくモデル化できないのです。 もちろん、この意見が通るような言語を使っていることが前提ですが(C/C++はこれが非常に難しいですし、Javaもそうです)。 要するに、利点は問題によって多少異なりますが、私は不変性を好む傾向があります。