Let's say there is a domain model:
@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; } } and it has updateDesc/updateName/updateSize/updateStock methods to call from service layer:
@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); } side note: those methods starting with update are no different than setter methods.
This is that simple, what it really means is that we eventually have a large model with a lot of fields i.e. customs declaration or some thing like this:
class ExampleModel{ field1:string field2:string field3:string ... field50:string ... state... money... } the fields1...50 are properties the user can freely change, just like a memo. How can it deal with this?
- create a patch class like HotelRoomPatch as a value bean under the domain layer, so the HotelRoom can handle it.
- define setter method with those fields so the service layer can call it.
- define updateXxx methods for them so the service layer can call it.
I think #1 is the same as #2, we can not protect our domain model.
I wonder how about your thinking?