承接模式三,Entity Bean 繼承 Value Object (Struct),但 getData()/setData() 仍需手動逐欄位複製。模式四在 Struct 新增 copyFrom(),實現一鍵複製。
public class CompanyStruct implements Serializable {
public Integer comId;
public String comName;
public String comDescription;
public Timestamp mutationDate;
// 新增:從另一 Struct 複製所有欄位
public void copyFrom(CompanyStruct struct) {
this.comId = struct.comId;
this.comName = struct.comName;
this.comDescription = struct.comDescription;
this.mutationDate = struct.mutationDate;
}
}
public class CompanyBean extends CompanyStruct implements EntityBean {
// getData():建立新 Struct,複製 this (Entity Bean 本身即 Struct)
public CompanyStruct getData() {
CompanyStruct result = new CompanyStruct();
result.copyFrom(this); // this 可視為 CompanyStruct
return result;
}
// setData():從參數 Struct 複製到 this
public void setData(CompanyStruct struct) {
this.copyFrom(struct);
}
// ejbCreate 同樣簡化
public Integer ejbCreate(CompanyStruct struct) throws CreateException {
this.comId = struct.comId; // 設定 PK
setData(struct); // 複製其餘欄位
return null;
}
}
| 議題 | 說明 |
|---|---|
| this 傳遞爭議 | EJB 規範不建議傳遞 this 參考(可能跨執行緒存取同一 Bean 實例導致交易衝突)。但此處 copyFrom 僅讀取欄位值,不涉及任何容器管理方法,故安全。 |
| 程式碼縮減 | 原需 4 次指派 → 1 行 copyFrom。欄位增減只需修改 Struct,Bean 完全不用動。 |
| 部署描述符同步 | CMP 欄位變更仍需更新 ejb-jar.xml,但 Java 程式碼已解耦。 |
public,違反封裝(可改用組合而非繼承)。現代專案棄用 EJB 2.x CMP,改用 JPA @Entity + @Embeddable Value Object:
@Entity
public class Company {
@Id Integer comId;
@Embedded CompanyDetails details; // Value Object
}
@Embeddable
public class CompanyDetails {
String comName;
String comDescription;
Timestamp mutationDate;
// 無需 copyFrom,JPA 自動管理生命週期
}
模式四展示「以 Value Object 為中心,透過複製方法消除重複指派」的實用技巧。雖 EJB 2.x 已成歷史,但「DTO 複製工具」(如 BeanUtils.copyProperties、MapStruct、Lombok @Builder)在現代開發中依然普遍應用,核心思想一脈相承。