13

このような不変のJavaオブジェクトが必要です(非常に単純化されています):

class Immutable {

    protected String name;

    public Immutable(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

}

場合によっては、オブジェクトを読み取り可能にするだけでなく変更可能にする必要があるため、継承によって可変性を追加できます。

public class Mutable extends Immutable {

    public Mutable(String name) {
        super(name);
    }

    public void setName(String name) {
        super.name = name;
    }

}

これは技術的には問題ありませんが、mutable が immutable 型でもあるということは、OOP と継承に準拠しているのだろうかと思います。UnsupportedOperationExceptionJava コレクション API のように、不変オブジェクトに対してスローされる OOP 犯罪を回避したいと考えています。

どう思いますか?他のアイデアはありますか?

4

5 に答える 5

14

親クラスを「不変」と呼ぶのは避けてください。これは、子クラスでは嘘になるためです。クラスを不変にたい場合は、この問題を正確に防ぐために、クラスも final にする必要があります。

Joda Time は "ReadableXXX" を使用して、「このクラスは読み取りアクセスのみを提供し、他のサブクラスは可変である可能性がある」という考えを与えます。そのアイデアが好きかどうかはわかりませんが、多くの代替案を見たとは言えません.

基本的に、問題はネガティブを表現するImmutableことにあります - あなたができないこと (それを変更すること) を説明し、サブクラスで賢明に強制することはできません。(その中のフィールドImmutableが final だったとしても、サブクラスが独自の変更可能なフィールドを持つことを止めることはありません。)

于 2010-03-22T16:26:10.260 に答える
5

継承可能なベースの「ReadableFoo」クラス、派生した封印されたImmutableFooクラス、およびその他の派生したMutableFooクラスが必要であることをお勧めします。Fooが可変であるかどうかを気にしないコードは、ReadableFooを受け入れることができます。変更されないことが保証されているFooが必要なコードは、ImmutableFooを受け入れることができます。Fooを変更する必要があるコードは、MutableFooを受け入れることができます。

ImmutableFooとMutableFooの両方のコンストラクターは、通常、ReadableFooを受け入れる必要があることに注意してください。そうすれば、Fooは可変または不変のバージョンに変換できます。

于 2011-01-23T02:55:13.040 に答える
5

あなたのサブクラスは、リスコフの置換原理に違反しているため、悪いです。やらないでください。

于 2010-03-22T16:39:06.980 に答える
3

不変クラスはfinal、可変サブタイプを正確に回避する必要があります。

不変クラスのサブタイプが不変の契約を破ることを許可すると、そもそもクラスを不変にすることはかなり無意味になります。Javaがそれを可能にするという意味では合法かもしれませんが(言語では不変性が強制されていません)、そのようなクラスは、サブクラス化できる限り、真に不変ではありません。

これが String が final である理由です。

于 2010-03-22T16:25:15.637 に答える
1

あなたのコードはかなり興味深いと思います。

Immutableこのような不変の動作を実装するには、オブジェクトに両方が含まれている間、getter メソッドのみを提供するインターフェイスに依存したいと思います。このように、不変オブジェクトに依存する操作はインターフェイスを呼び出し、他の操作はオブジェクトを呼び出します。

また、不変オブジェクトを可変オブジェクトとしてキャストしたくない場合は、プロキシとすべてのエンタープライズ ツール (アスペクトなど) を使用できます。しかし、通常、他の開発者の善意に頼ることは、彼らに自分の間違いの責任を負わせるための良い方法です (不変を可変にキャストするなど)。

于 2010-03-22T16:31:45.567 に答える