Một trong những lý do tôi nghĩ rằng cuộc thảo luận này xuất hiện nhiều lần là vì có vẻ như một kẻ đau khổ nghiêm trọng khi lấy một vật thể với tất cả dữ liệu bạn cần và chuyển đổi nó thành một vật thể trông giống hệt hoặc gần giống với vật thể đó bạn đang bàn giao
Đó là sự thật, đó là một PITA. Nhưng có một vài lý do (ngoài những điều được liệt kê ở trên) để làm như vậy.
- Các đối tượng miền có thể rất nặng và chứa nhiều thông tin vô dụng cho cuộc gọi. Sự phình to này làm chậm giao diện người dùng vì tất cả các dữ liệu được truyền, sắp xếp / không được sắp xếp và phân tích cú pháp. Khi bạn xem xét một FE sẽ có rất nhiều liên kết đề cập đến dịch vụ web của bạn và được gọi bằng AJAX hoặc một số phương pháp tiếp cận đa luồng khác, bạn sẽ nhanh chóng khiến giao diện người dùng của mình chậm chạp. Tất cả điều này đạt đến khả năng mở rộng chung của dịch vụ web
- Bảo mật có thể dễ dàng bị xâm phạm bằng cách tiết lộ quá nhiều dữ liệu. Tối thiểu bạn có thể tiết lộ địa chỉ email và số điện thoại của người dùng nếu bạn không loại bỏ chúng khỏi kết quả DTO.
- Cân nhắc thực tế: Để 1 đối tượng diễu hành như một đối tượng miền bền bỉ VÀ DTO, nó sẽ phải có nhiều chú thích hơn mã. Bạn sẽ có bất kỳ số vấn đề nào với việc quản lý trạng thái của đối tượng khi nó đi qua các lớp. Nói chung, điều này giống với PITA hơn nhiều để quản lý sau đó chỉ đơn giản là thực hiện các thao tác sao chép các trường từ một đối tượng miền sang DTO.
Nhưng, bạn có thể quản lý nó khá hiệu quả nếu bạn gói logic dịch vào một tập hợp các lớp trình chuyển đổi
Hãy xem lambdaJ nơi bạn có thể thực hiện 'convert (domainObj, toDto)' có quá tải điều này để sử dụng với các bộ sưu tập. Dưới đây là một ví dụ về một phương thức điều khiển sử dụng nó. Như bạn có thể thấy, nó trông không tệ lắm.
@GET
@Path("/{id}/surveys")
public RestaurantSurveys getSurveys(@PathParam("id") Restaurant restaurant, @QueryParam("from") DateTime from, @QueryParam("to") DateTime to) {
checkDateRange(from, to);
MultiValueMap<Survey, SurveySchedule> surveysToSchedules = getSurveyScheduling(restaurant, from, to);
Collection<RestaurantSurveyDto> surveyDtos = convert(surveysToSchedules.entrySet(), SurveyToRestaurantSurveyDto.getInstance());
return new RestaurantSurveys(restaurant.getId(), from, to, surveyDtos);
}