只是拿了一个比较典型的例子(订单),类似这种例子非常的多。当然不是说适用于所有的情况。
只是刚才回帖之后,一时兴起拿出来与大家做一个小的分享。不知道对你是否有用。public class Order {
private String name;
//
private Set<OrderLine> orderLines = new HashSet<OrderLine>(); public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} /**
* 因为这是一个domain对象,贯穿你整个项目,不知你是否在意过这样的设计。
* 这样的设计对你是否有用呢?
* 用户:表示API调用者。
*/
public Set<OrderLine> getOrderLines() {
/*
* 1.防止用户任意修改订单行的内容,强制要求用户使用当前类提供的API修改订单行
* 2.getOrderLines()绝对不为null,有可能getOrderLines().isEmpty()为true
* 用在你的程序中不会出现if(getOrderLines() == null && getOrderLines().isEmpty()),
* 只会出现if(getOrderLines().isEmpty())
*/
return Collections.unmodifiableSet(orderLines);
} //-----------------------提供API修改Order by OrderLine----------------------------//
public void addOrderLine(OrderLine orderLine) {
//
orderLines.add(orderLine);
} public void removeOrderLine(OrderLine orderLine) {
// ...
}
//-----------------------提供API修改Order by OrderLine----------------------------//
public void setOrderLines(Set<OrderLine> orderLines) {
// this.orderLines = orderLines;
// 为什么没有向上面来做,是因为如果是这样赋值的话那么两个对象就是同一个引用了。
// 用户修改orderLines,this.orderLines也同样会被修改。
// 而提供这个类期望用户通过该类提供的接口来修改orderLines。
orderLines.addAll(orderLines);
}}
只是刚才回帖之后,一时兴起拿出来与大家做一个小的分享。不知道对你是否有用。public class Order {
private String name;
//
private Set<OrderLine> orderLines = new HashSet<OrderLine>(); public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} /**
* 因为这是一个domain对象,贯穿你整个项目,不知你是否在意过这样的设计。
* 这样的设计对你是否有用呢?
* 用户:表示API调用者。
*/
public Set<OrderLine> getOrderLines() {
/*
* 1.防止用户任意修改订单行的内容,强制要求用户使用当前类提供的API修改订单行
* 2.getOrderLines()绝对不为null,有可能getOrderLines().isEmpty()为true
* 用在你的程序中不会出现if(getOrderLines() == null && getOrderLines().isEmpty()),
* 只会出现if(getOrderLines().isEmpty())
*/
return Collections.unmodifiableSet(orderLines);
} //-----------------------提供API修改Order by OrderLine----------------------------//
public void addOrderLine(OrderLine orderLine) {
//
orderLines.add(orderLine);
} public void removeOrderLine(OrderLine orderLine) {
// ...
}
//-----------------------提供API修改Order by OrderLine----------------------------//
public void setOrderLines(Set<OrderLine> orderLines) {
// this.orderLines = orderLines;
// 为什么没有向上面来做,是因为如果是这样赋值的话那么两个对象就是同一个引用了。
// 用户修改orderLines,this.orderLines也同样会被修改。
// 而提供这个类期望用户通过该类提供的接口来修改orderLines。
orderLines.addAll(orderLines);
}}
但是设计的面都是差不多的。并且这些对象都随着业务的改变而改变。所以我只是写了一个大概。
“用在你的程序中不会出现if(getOrderLines() == null && getOrderLines().isEmpty()),”
当然不可能出现,只可能出现NPE,如果出现true的话,那就是getOrderLines()方法不是幂等的。另外,建议使用linkedhashset,以保持顺序。同时,考虑是否有多线程问题。单单这一段代码,在多线程下面会有问题
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;public class Order<T> {// 顺便泛化吧 private String name;
//
private Set<T> orderLines = new HashSet<T>(); public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} /*
* synchronized (mutex) {
* }
*/
public boolean addOrderLine(T orderLine) {// 返回值改为布尔值好一点
if (orderLine == null)
return false;
return orderLines.add(orderLine);
} public boolean removeOrderLine(T orderLine) {// 返回值改为布尔值好一点 if (orderLine == null)
return false;
return orderLines.remove(orderLine);
} // 还可以适当添加clear() removeAll(Collection<T> c),addAll(Collection<T> c)
// 还可以适当添加 size iterator(),contains(Object o) toArray()常用方法 public void setOrderLines(Set<T> orderLines) {
orderLines.addAll(orderLines);// 这里写成allAll感觉怪怪的,写成this.orderLines =
// orderLines
} public Set<T> getOrderLines() {
return Collections.unmodifiableSet(orderLines);
} // //////////////////////////////////////////////////////////////////// private Order() { } private Order(String name) {
this.name = name;
} private Order(Set<T> orderLines) {
this.orderLines = orderLines;
} private Order(String name, Set<T> orderLines) {
this.name = name;
this.orderLines = orderLines;
} public Order<T> getInstance() {
return new Order<T>();
} public Order<T> getInstance(String name) {
return new Order<T>(name);
} public Order<T> getInstance(Set<T> orderLines) {
return new Order<T>(orderLines);
} public Order<T> getInstance(String name, Set<T> orderLines) {
return new Order<T>(name, orderLines);
} public String toString() {//
return String.format("name = %s ", name, orderLines);
}
}
假设线程A使用:
Order order = new Order();
而线程B使用:
Order order = new Order();这两个线程都有一个order对象,假设这两个对象对应的流水号是一样的。
但是却是两个完全不同的对象应该不存在线程安全的问题。当然如果有特殊的情况需要多个线程共享同一个order对象,那么就必须要通过其它的手段来达成目的,那么在哪里做上线程同步也同样可以避免线程带来的问题。
所以我觉得这个domain没有考虑线程方面的问题,这没有问题。
对于朋友所说的使用LinkedHashSet,我觉得这就得根据需求来选择了。