他のデータ構造を使用する代わりにHashSetのようなSet実装を使用することで、重複がないことを確認できます。Jobを顧客に追加する代わりに、プライベート コンストラクターを持つ Job クラスに最終的な内部クラスを作成します。これにより、ラッパーの内部クラスはジョブ オブジェクトによってのみ作成できるようになります。Job コンストラクターにjobIDと customer をパラメーターとして取り込ませます。一貫性を維持するため - 顧客が Null の場合、ダミー ジョブを作成しないため、例外をスローします。
Customer のaddメソッドで、 JobUnit でラップされたJobが自身の ID と同じ顧客 ID を持っているかどうかを確認し、そうでない場合は Exception をスローします。
Job クラスの顧客を置き換える場合、Customer クラスによって提供されるメソッドを使用してJobUnitを削除し、それ自体を新しい顧客に追加して、顧客参照を新しく渡された顧客に変更します。そうすれば、コードをより適切に推論できます。
顧客クラスは次のようになります。
public class Customer {
Set<JobUnit> jobs=new HashSet<JobUnit>();
private Long id;
public Customer(Long id){
this.id = id;
}
public boolean add(JobUnit unit) throws Exception{
if(!unit.get().getCustomer().id.equals(id))
throw new Exception(" cannot assign job to this customer");
return jobs.add(unit);
}
public boolean remove(JobUnit unit){
return jobs.remove(unit);
}
public Long getId() {
return id;
}
}
そしてジョブクラス:
public class Job {
Customer customer;
private Long id;
最終的な JobUnit 単位。
public Job(Long id,Customer customer) throws Exception{
if(customer==null)
throw new Exception("Customer cannot be null");
this.customer = customer;
unit= new JobUnit(this);
this.customer.add(unit);
}
public void replace(Customer c) throws Exception{
this.customer.remove(unit);
c.add(unit);
this.customer=c;
}
public Customer getCustomer(){
return customer;
}
/**
* @return the id
*/
public Long getId() {
return id;
}
public final class JobUnit{
private final Job j;
private JobUnit(Job j){
this.j = j;
}
public Job get(){
return j;
}
}
}
しかし、私が興味を持っていることの 1 つは、なぜ顧客オブジェクトにジョブを追加する必要があるのかということです。どの顧客がどのジョブに割り当てられているかを確認するだけの場合は、ジョブを検査するだけでその情報が得られます。通常、やむを得ない場合を除き、循環参照を作成しないようにしています。また、ジョブが作成された後に顧客を置き換える必要がない場合は、Jobクラスの顧客フィールドを Final にし、メソッドを削除して設定または置き換えます。
ジョブに顧客を割り当てるための制限はデータベースで維持する必要があり、データベース エントリはチェック ポイントとして使用する必要があります。他の誰かのために行われた顧客へのジョブの追加に関しては、ジョブの顧客参照をチェックして、ジョブが追加されている顧客が保持している顧客と同じであることを確認するか、またはより良い方法で、単に参照を削除することができます。仕事の顧客とそれはあなたのために物事を簡素化します。