[英]business logic in domain objects
有這個課程:
public class DataPeriod {
private final String key;
private final LocalDate from;
private final LocalDate to;
private final Map<LocalDate, DataPoint> dataPoints = new HashMap<LocalDate, DataPoint>();
public DataPeriod(String key, LocalDate from, LocalDate to) {
this.key = key;
this.from = from;
this.to = to;
}
public LocalDate getFrom() {
return from;
}
public LocalDate getTo() {
return to;
}
public void hit(int id) {
DataPoint dataPoint = getOrCreate();
dataPoint.hit(id);
}
private DataPoint getOrCreate() {
LocalDate now = LocalDate.now();
String dataPointKey = key + now.toString();
if ( !dataPoints.containsKey(now) ) {
DataPoint dataPoint = new DataPoint(dataPointKey);
dataPoints.put(now, dataPoint);
}
return dataPoints.get(dataPointKey);
}
public long count() {
long count = 0l;
for (DataPoint dataPoint : dataPoints.values()) {
count += dataPoint.count();
}
return count;
}
可能是一個好主意將方法hit(int id)
和getOrCreate()
作為服務或幫助程序提取到其他類。 但是應該修改它們以便接收DataPoint
參數。
我認為將它們包含在DataPoint
類中是有意義的,因為它們代表DataPeriod
必須知道的動作。
這種情況有一些模式嗎? 在並發提取或不提取方面這些方法有什么區別?
我認為最好將方法保留在同一個模型類中,如果它們只使用同一個類中的數據,或者換句話說,如果它們不依賴於其他類。
當然,您永遠不會從模型類訪問服務,但有時很難確定模型類是否應該使用另一個模型類。 這取決於關系是否緊密(例如,一個包含另一個,並且所包含的類永遠不會獨立使用)。 如果兩個模型類沒有很強的相關性,那么一個不應該管理另一個; 在這種情況下,我會將工作留給第三個外部類(如服務或只是包含其他類的另一個模型類)。
在你的情況下, DataPeriod
包含dataPoints
(可能是另一個模型類)所以我認為將方法保留在那里是好的。
這看起來像是使用動態屬性的經典案例。
如果您有一個可以從其他屬性計算的屬性,則將其聲明為動態屬性並為其編寫自定義屬性處理程序 。
例如 - 如果您有持久屬性(存儲在數據庫中的屬性),如出生日期,那么您可以聲明動態屬性年齡並在運行時計算它而不將其存儲在數據庫中。 您將需要一個自定義動態屬性處理程序,如AgeAttributeHandler.java
。
擁有動態屬性的另一個動機是spring bean約定,所有模型bean 必須 只有 getter和setter 。 業務邏輯應保留在模型bean之外。
在您的情況下,首先創建一個DynamicAttributeHandler.java
-
public interface DynamicAttributeHandler<VALUE, MODEL extends Object> {
VALUE get(MODEL var1);
void set(MODEL var1, VALUE var2);
}
然后,為count
和dataPoints
創建動態屬性處理程序 。
public class CountAttributeHandler implements DynamicAttributeHandler<Long, DatePeriod> {
@Override
public Long get(DatePeriod model) {
long count = 0l;
Map<LocalDate, DataPoint> dataPoints = model.getDataPoints();
for (DataPoint dataPoint : dataPoints.values()) {
count += dataPoint.count();
}
return count;
}
@Override
public void set(DatePeriod model, Long aLong) {
}
}
public class DataPointsAttributeHandler implements DynamicAttributeHandler<Map<LocalDate, DataPoint>, DatePeriod> {
@Override
public Map<LocalDate, DataPoint> get(DatePeriod model) {
LocalDate now = LocalDate.now();
String dataPointKey = model.getKey() + now.toString();
Map<LocalDate, DataPoint> dataPoints = model.getDataPoints();
if (!dataPoints.containsKey(now)) {
DataPoint dataPoint = new DataPoint(dataPointKey);
dataPoints.put(now, dataPoint);
}
return dataPoints;
}
@Override
public void set(DatePeriod model, Map<LocalDate, DataPoint> localDateDataPointMap) {
}
}
現在,可以使用getter和setter創建模型。
public class DatePeriod {
private final String key;
private final LocalDate from;
private final LocalDate to;
private final Map<LocalDate, DataPoint> dataPoints;
private final long count;
public DatePeriod(String key, LocalDate from, LocalDate to, Map<LocalDate, DataPoint> dataPoints, long count) {
this.key = key;
this.from = from;
this.to = to;
this.dataPoints = dataPoints;
this.count = count;
}
public LocalDate getFrom() {
return from;
}
public LocalDate getTo() {
return to;
}
public String getKey() {
return key;
}
public Map<LocalDate, DataPoint> getDataPoints() {
DynamicAttributeHandler<Map<LocalDate, DataPoint>, DatePeriod> dataPointsAttributeHandler = new DataPointsAttributeHandler();
return dataPointsAttributeHandler.get(this);
}
public long getCount() {
DynamicAttributeHandler<Long, DatePeriod> countAttributeHandler = new CountAttributeHandler();
return countAttributeHandler.get(this);
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.