Thực thể sử dụng DTO


15

Đã cố gắng đưa ra một luồng cho một ứng dụng web cơ bản và đã đọc thông tin xung đột trực tuyến. Điều tôi đang cố gắng tìm hiểu là liệu có lợi thế gì khi vẫn sử dụng các đối tượng DTO từ lớp DAO đến Dịch vụ của bạn thông qua việc sử dụng một số loại trình ánh xạ.

Luồng cơ bản mà tôi thấy trước như sau:

  1. Mô hình / Mẫu UI -> Bộ điều khiển
  2. Trình điều khiển chuyển đổi Mô hình thành Đối tượng Miền (Thực thể)
  3. Đối tượng miền -> Lớp dịch vụ
  4. Đối tượng miền -> DAO
  5. DAO -> Đối tượng tên miền
  6. Dịch vụ -> Giao diện người dùng
  7. UI chuyển đổi tên miền thành các mô hình UI

Nếu DTO được theo dõi, DAO sẽ trả lại DTO chứ không phải Thực thể. Sau khi đọc một số thứ, có vẻ như DTO đã trở nên hơi thiếu sót vì (ít nhất là trong Java) các thực thể đã được chú thích POJO có nghĩa là dấu chân bộ nhớ của chúng đã trở nên rất nhỏ.

Đây có phải là trường hợp không, hay DTO nên được sử dụng để đóng gói hoàn toàn các đối tượng miền trong lớp DAO và, nếu đây là trường hợp, lớp dịch vụ sẽ chuyển sang DAO gì?

Cảm ơn nhiều!

Câu trả lời:


20

Theo tôi, vượt qua một POJO bền bỉ, ví dụ như một hạt đậu được quản lý bởi JPA, không phải là cách làm tốt.

Tại sao?

Tôi thấy ba lý do chính:

  1. Vấn đề tiềm năng với bộ sưu tập lười biếng. http://java.dzone.com/articles/avoid-lazy-jpa-collections
  2. Thực thể phải chứa hành vi (trái với mô hình miền Thiếu máu ) Bạn có thể không muốn để UI của mình gọi một số hành vi không mong muốn.
  3. Trong trường hợp mô hình miền thiếu máu, bạn có thể không muốn đưa cấu trúc mô hình của mình ra UI, vì mọi thay đổi mới đối với mô hình có thể phá vỡ UI.

Tôi thích để lớp dịch vụ của mình chuyển đổi các thực thể thành DTO tương ứng theo cả hai hướng. DAO vẫn trả lại thực thể (đó không phải là công việc của nó để đảm bảo chuyển đổi).


Vì vậy, nếu tôi hiểu điều này một cách chính xác, về cơ bản, dịch vụ chỉ xử lý các đối tượng DTO và đóng vai trò là trung gian của cả UI và DAO. Ngoài ra, ở điểm 3, bạn vẫn phải chuyển DTO thành các thành phần UI khả thi, do đó, bản cập nhật tên miền vẫn không phá vỡ giao diện người dùng do DTO cũng cần cập nhật.
dardo

1
Các thành phần UI @dardo là DTO, hoặc tệ nhất, nên được chuyển đổi thành DTO trước khi gọi một số dịch vụ ở phía máy chủ. DTO không có khả năng thường xuyên thay đổi, chỉ có sự thích ứng từ các thực thể của bạn tập trung vào nhu cầu UI. Bên cạnh đó, lớp dịch vụ nên quan tâm đến cả hai: DTO và các thực thể.
Mik378

À được rồi, có tiếng nấc tôi không hiểu. Mô hình miền thiếu máu khá phổ biến ở nơi tôi làm việc và tôi đang cố gắng thay đổi mô hình một chút để khuyến khích lớp dịch vụ mỏng hơn. Cảm ơn một lần nữa!
dardo

@dardo Bạn có thể đọc cuốn sách này. (hoặc hiển thị nó cho công ty của bạn;)) Cuốn sách tuyệt vời: amazon.com/Imcellenceing-Domain-Driven-Design-Vaughn-Vernon/dp/
Lỗi

thực sự đã có cái này trên kindle, amazon.com/Domain-Driven-Design-Tackling-Complexity-Software/dp/ mẹo khá tốt cho đến nay = D
dardo

13

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);

    }

Cảm ơn về đầu vào, và suy nghĩ của tôi là cùng một dòng =)
dardo
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.