您可以通过使用像HashSet这样的Set实现而不是使用其他数据结构来确保没有重复项。而不是将Job添加到客户,而是在 Job 类中创建一个具有私有构造函数的最终内部类。这确保了包装器内部类只能由作业对象创建。让您的 Job 构造函数以jobID和 customer 作为参数。为了保持一致性 - 如果客户为 Null,则抛出异常,因为不应创建虚拟作业。
在 Customer的add方法中,查看JobUnit包裹的Job是否与自己的id相同的customer ID,如果没有则抛出异常。
在 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;
}
}
}
但我很好奇的一件事是,为什么您甚至需要向客户对象添加工作?如果您只想检查哪个客户已分配到哪个工作,只需检查一个工作即可为您提供该信息。一般来说,除非不可避免,否则我尽量不创建循环引用。此外,如果不需要在创建工作后从工作中替换客户,只需在Job类中将客户字段设为 Final 并删除方法来设置或替换它。
应在数据库中维护为工作分配客户的限制,并且应将数据库条目用作检查点。至于向客户添加为其他人完成的工作,您可以检查工作中的客户参考,以确保要添加工作的客户与其持有的客户相同,甚至更好 -只需删除中的任何参考Job 的客户,它将为您简化事情。