オブジェクトとオブジェクトのリストを返すときに問題が発生します。問題は、開発者の例ではオブジェクトを返したいが、参照は与えたくないということです。これのための最良のアプローチは何ですか?まず、新しい開発者を返すだけだと思っていました。
public Developer getDeveloper(int index){
Developer d = developers.get(index);
return new Developer(d.getName());
}
しかし、これは単純なオブジェクトには良さそうですが、オブジェクトまたはリストでもあるインスタンスフィールドを持つ開発者オブジェクトがある場合はどうなりますか?
他の質問は、開発者のリストを返すリストについてです:
public List<Developer> getDeveloppers(){
return Collections.unmodifiableList(this.developers);
}
そのため、リストは変更できなくなりましたが、オブジェクトは変更できないと思います...変更できないオブジェクトを含むリストを返すにはどうすればよいですか?
コード例:
import Java.util.ArrayList;
import Java.util.Collections;
import Java.util.List;
public class Project {
private List<Developer> developers;
private String name;
public Project(){
this("DEFAULT");
}
public Project(String name){
this.setName(name);
this.developers = new ArrayList<Developer>();
}
public List<Developer> getDeveloppers(){
return Collections.unmodifiableList(this.developers);
}
public Developer getDeveloper(int index){
Developer d = developers.get(index);
return new Developer(d.getName());
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
開発者クラス、これにはインスタンスオブジェクトがないことに注意してください。
public class Developer {
private String name;
public Developer(String name){
this.name = name;
}
public String getName(){
return this.name;
}
}
助けていただければ幸いです!よろしく
オブジェクトを不変にすることができます:
_public class Developer {
private final String name;
public Developer(String name){
this.name = name;
}
public String getName(){
return this.name;
}
}
_
その後、参照を返すことに問題はありません。
それ以外の場合は、各開発者をそれ自体の変更不可能なビューにマップできます。
_public Stream<IDeveloper> getDeveloppers(){
return this.developers.map(dev => dev.unmoddifiableView());
}
_
unmoddifiableView()
は、変更を許可しないIDeveloperのインスタンスを返します。
_private static IDeveloper readOnlyView = new UnmodifiableDeveloper(this);
public IDeveloper unmoddifiableView(){
return readOnlyView;
}
_
UnmodifiableDeveloperは、すべてのゲッターをコンストラクターパラメーターに委任します。
あなたが説明していることを行う直接的な方法はありません。ただし、希望どおりの結果が得られるオプションがいくつかあります。
.clone()
メソッドの可能性があります。これはクラスの新しいインスタンスを返すはずですが、同じ情報を表す状態です(たとえば、name
は同じです)。次に、元のクラスを返す代わりに、コピーを返します。これらは引き続き変更可能ですが、これらのインスタンスを変更しても元のインスタンスには影響しません。これらがあなたが制御するクラスであると仮定すると、4は私の圧倒的なお気に入りのオプションであり、除外する十分な理由がない限り、間違いなく最初の目的でなければなりません。いくつかの理由:
カプセル化に関する本当に便利な点の1つは、クラスがその状態について仮定を立てることができることです。ただし、これらの仮定をtrueに保つ責任も負います。例として、Fraction
クラスがあります。このクラスが独自のカプセル化された状態を管理し、それ自体を縮小形式で保持する場合、そのequals
メソッドは次のようになります。
_equals(Object obj) {
return obj.numerator = numerator && obj.denominator = denominator;
}
_
numerator
とdenominator
がカプセル化されていなかった場合、それが縮小された形式であるかどうか確信が持てず、より複雑なロジックを使用して確認する必要があります。たとえば、_1/2
_と_2/4
_は等しいと比較されます。これはクラス不変と呼ばれます。クラスを使用するたびに、その不変条件を保護することを忘れないようにして、バグと恐らく恐ろしく結合されたコードへの確実なルートになることを期待してください。これは、前の箇条書きの別の側面です。.clone()
などを呼び出すことを覚えておくためにこのクラスを使用するすべてのクラスに依存している場合、カプセル化の責任を裏返しにしています。
haveでこれを行う(またはそれを行わない場合のコストが高すぎる)状況に自分がいる場合、他のすべての条件が同じであれば、オプション1をお勧めします。インターフェースの比較的自然な使用。