私のクラスの 1 つに、セットを含むフィールドがあります。このフィールドは、コンストラクターでのみ入力され、他のクラスによって読み取られます。もともと私は次のようなものを持っていました:
public class Foo {
public final Set<String> myItems;
public Foo(Collection<String> theirItems) {
this.myItems = new LinkedHashSet<String>(theirItems);
}
}
しかし、これは、myItems を非公開にし、setter と getter を介してのみアクセスする必要があるという OO のベスト プラクティスに反します。それで、私はそれを次のように変更しました:
public class Foo {
private final Set<String> myItems;
public Foo(Collection<String> theirItems) {
this.myItems = new LinkedHashSet<String>(theirItems);
}
public Set<String> getItems() {
return myItems;
}
}
これで myItems は非公開になりましたが、 getItems() を呼び出す人は誰でも自由にアイテムを追加/削除できます。これは基本的に以前と同じ状況です。(私は実際に誰かがアイテムの内容を変更することを心配していません。これはより理論的な質問です)
そこで、配列を返すように getItems() を変更しました。
public String[] getItems() {
return myItems.toArray(new String[myItems.size()]);
}
今、私のアイテムは本当にプライベートです。残念ながら、アイテムを読み取るオブジェクトが実際に Set を操作する必要があることはわかっているため、配列をすぐに元に戻す必要があります。myItems のコピーを返すこともできます。
public Set<String> getItems() {
return new LinkedHashSet<String>(myItems);
}
これにより、呼び出し元に必要なものが提供されますが、アクセスごとに新しい Set が作成されます。
このような状況であなたはどうしますか? プライバシーを何としても保護し、元の構造の変換/コピーを受け入れるか、コレクションの内容に対する制御を犠牲にして責任ある呼び出し元に依存しますか?