假设我有一个领域模型
@Table(name = "room")
@Getter
@FieldNameConstants
@AllArgsConstructor(onConstructor = @__({@PersistenceCreator}))
public class HotelRoom extends AbstractEntity implements HotelAware, Sellable {
@Id
private final String id;
@Column(value = "hotel_id")
private final String hotelId;
@Column(value = "name")
private String name;
@Column(value = "size")
private RoomSize size;
@Column(value = "sale_state")
private SaleState saleState;
@Embedded.Empty
private Stock stock;
@Embedded.Empty
private RoomDesc desc;
private HotelRoom(String roomId, String hotelId) {
this.id = roomId;
this.hotelId = hotelId;
}
public static HotelRoom create(String id, Hotel hotel, String name, RoomDesc desc, RoomSize size, Stock stock) {
DomainUtils.must(stock.greaterTan(Stock.ZERO), () -> new IllegalArgumentException("stock must gather than zero"));
var hotelId = hotel.getId();
var room = new HotelRoom(id, hotelId);
room.name = name;
room.size = size;
room.stock = stock;
room.desc = desc;
room.saleState=SaleState.STOPPED;
return room;
}
@Override
public void startSale() {
this.saleState = SaleState.STARTED;
}
@Override
public void stopSale() {
this.saleState = SaleState.STOPPED;
}
@Override
public SaleState getSaleState() {
return this.saleState;
}
@Override
public boolean isOnSale() {
return saleState.isOnSale();
}
public void updateDesc(RoomDesc desc) {
this.desc = desc;
}
public void updateName(String name) {
this.name = name;
}
public void updateSize(RoomSize size) {
this.size = size;
}
public void updateStock(Stock stock) {
this.stock = stock;
}
}
它有 updateDesc/updateName/updateSize/updateStock 这些我将在服务层调用的方法。
@Override
public void updateRoom(RoomUpdateCommand command) {
var room = hotelRoomRepository.requireById(command.getRoomId());
room.updateDesc(RoomDesc.builder()
.desc(command.getDesc())
.build());
room.updateName(command.getName());
room.updateSize(command.getSize());
room.updateStock(command.getStock());
hotelRoomRepository.save(room);
}
但我认为那些从 update 开始的方法与 setter 方法没有区别。
这很简单,我真正的意思是我们最终拥有一个包含很多字段的大型模型,即海关申报或类似的东西:
class ExampleModel{
field1:string
field2:string
field3:string
...
field50:string
...
state...
money...
}
fields1...50 是用户可以自由更改的属性,就像备忘录一样。
我该如何处理这个问题?
我认为#1与#2相同,我们无法保护我们的领域模型。
不知道你的想法如何?
一种可能的解决方案可能是用一个方法替换许多“更新”方法。
class HotelRoom {
// fields and constructors
void apply(HotelRoomPatch patch) {
// logic of update
}
}
interface HotelRoomPatch {
Optional<String> name();
Optional<SaleState> saleState();
// etc.
}