Lớp dịch vụ so với DAO - Tại sao cả hai?


64

Tôi đã làm việc với SpringMVC, Hibernate và một số cơ sở dữ liệu trong một ví dụ ứng dụng web java.

Có một vài cái khác nhau thực hiện điều này, nhưng ví dụ về hướng dẫn tích hợp ngủ đông và mùa xuân 3 này có một lớp mô hình, khung nhìn (trong jsp), và một lớp dịch vụ và dao cho bộ điều khiển.

Câu hỏi của tôi là, không phải cả hai lớp dịch vụ và DAO đều làm điều tương tự? Tại sao bạn cần cả hai?

Đây là hướng dẫn tôi thực sự đang sử dụng: http://fruzenshtein.com/spring-mvc-security-mysql-hibernate/

Câu trả lời:


60

Nói chung, DAO càng nhẹ càng tốt và chỉ tồn tại để cung cấp kết nối với DB, đôi khi được trừu tượng hóa để có thể sử dụng các phụ trợ DB khác nhau.

Lớp dịch vụ ở đó để cung cấp logic để vận hành trên dữ liệu được gửi đến và từ DAO và máy khách. Rất thường 2 phần này sẽ được bó lại với nhau trong cùng một mô-đun và đôi khi thành cùng một mã, nhưng bạn vẫn sẽ thấy chúng là các thực thể logic riêng biệt.

Một lý do khác là bảo mật - Nếu bạn cung cấp một lớp dịch vụ không liên quan đến DB, thì việc truy cập DB từ máy khách sẽ khó khăn hơn ngoại trừ thông qua dịch vụ. Nếu DB không thể được truy cập trực tiếp từ máy khách (và không có mô-đun DAO tầm thường nào đóng vai trò là dịch vụ) thì tất cả kẻ tấn công đã chiếm quyền máy khách cũng có thể cố gắng hack lớp dịch vụ trước khi anh ta có được tất cả trừ truy cập vệ sinh nhất vào dữ liệu của bạn.


1
Tôi đồng ý với việc tách lớp dịch vụ và dao và lớp dịch vụ chứa logic kinh doanh của bạn.
Peter Delaney

không đề cập đến việc 1 dịch vụ có thể gọi một số DAO, ví dụ: khi lưu người dùng, bạn có thể nói chuyện với UserDao, UserOrderDao, v.v. Hoặc chúng ta nên tạo một dịch vụ cho mỗi dịch vụ? Và ai có thể gọi tất cả các dịch vụ này?
Fermin Silva

40

Tôi là người viết bài trong câu hỏi. Tôi đã có phần chia sẻ công bằng của mình khi làm việc trên các công nghệ khác nhau và các kiến ​​trúc khác nhau. Dựa vào bên trên, tôi có thể nói một cách an toàn rằng có lớp dịch vụ và lớp dao luôn là một ý tưởng tốt. DAO nên được giới hạn chỉ thêm / cập nhật / chèn / chọn các đối tượng Thực thể vào / từ cơ sở dữ liệu và đó là tất cả. Nếu bạn muốn làm bất cứ điều gì thêm về mặt logic, hãy thêm nó vào lớp dịch vụ. Điều này sẽ giúp tạo mã theo mô-đun và dễ dàng thay thế khi cơ sở dữ liệu được thay thế (đối với một phần dữ liệu). Điều này đặc biệt áp dụng trong các ứng dụng liên quan đến các báo cáo có logic nặng ngay cả sau khi tìm nạp dữ liệu từ cơ sở dữ liệu.

Ngoài ra, vào mùa xuân, bảo mật được áp dụng ở lớp dịch vụ lý tưởng. Bạn sẽ không muốn thay đổi theo cách này.


5
Này, cảm ơn rất nhiều vì đã trả lời câu hỏi của tôi; đó là sự cống hiến cho blog của bạn! Cảm ơn ví dụ tuyệt vời, tiếp tục viết.
Jeff

Điều này đã làm tôi suy nghĩ một lúc và tôi nghĩ kinh nghiệm giúp ích nhiều nhất trong những tình huống này. Cảm ơn bạn.
Utku zdemir

Tôi đồng ý với việc phân tách các lớp dịch vụ và dao và lớp dịch vụ của bạn chứa logic nghiệp vụ của bạn và chỉ gọi các phương thức Dao. Điều gì về khi một trong các phương thức dịch vụ của tôi cần gọi một phương thức dịch vụ khác. Tôi có nên có một sự trừu tượng hóa khác bên trên lớp dịch vụ gọi nhiều phương thức dịch vụ không?
Peter Delaney

Không. Các lớp ở lớp dịch vụ có thể có tham chiếu lẫn nhau (khi cần) và chúng có thể gọi các phương thức cần thiết.
lokesh

11

Adam Bien chỉ ra trong cuốn sách của mình một thực tế rằng JPA EntityManager là một triển khai phổ biến tốt của DAO:

http://realworldpotypes.com/

Trong thế giới Java EE, hầu như không bao giờ cần phải viết DAO của riêng bạn vì các triển khai JPA bao gồm một. Bạn chỉ phải viết lớp dịch vụ.

Việc thực hiện lớp DAO của riêng bạn thực sự là một sự nôn nao từ kiến ​​trúc J2EE rất kém của 15 năm trước, nhưng nhiều người vẫn cảm thấy bắt buộc phải làm điều đó. Các lớp DAO tùy chỉnh này thường không cung cấp gì nhiều hơn các hàm chuyển tiếp gọi phương thức tương ứng trên EntityManager.

Vì vậy, để trả lời câu hỏi của bạn, có bạn cần một lớp dịch vụ và DAO, nhưng bạn chỉ phải viết lớp dịch vụ.


2
Tôi không chắc nếu điều đó áp dụng cho Spring - luôn có một DAO tùy chỉnh cần được tạo cho Model. Có lẽ câu nói của bạn "gần như không bao giờ cần phải viết DAO của riêng bạn" áp dụng riêng cho máy chủ ứng dụng / bộ chứa EJB?
Don Cheadle

1
Tốt hơn là bạn nên tự viết (DAO / DAOImpl), mặc dù nó sẽ chỉ ánh xạ tới EntityManager - Đó là vì trong tương lai bạn có thể thêm một triển khai DAO khác mà không cần thay đổi mã lớp dịch vụ .
ahmednabil88

@YajliMaclo có gì khác biệt để thay đổi?
Alex78191

4

Tôi thường đặt tất cả mã db cụ thể (truy vấn) trong DAO và xử lý giao dịch và logic nghiệp vụ trong các dịch vụ. Điều này cho phép các phương thức dịch vụ gọi các phương thức trên nhiều dao và giữ tất cả trong cùng một giao dịch. Theo tôi, điều này cho phép tái sử dụng mã tốt hơn trên dao.


2

Tôi đã thấy rằng lớp dịch vụ thêm sự phức tạp không cần thiết trong hầu hết các trường hợp. Về lý thuyết là để tránh logic kinh doanh trong lớp dao nhưng cuối cùng, điều này chỉ dẫn đến sự nhầm lẫn, thậm chí một số người đã không đồng ý loại bỏ hoàn toàn lớp dao vì họ cảm thấy nó không thêm giá trị. http://ayende.com/blog/4784/architecting-in-the-pit-of-doom-the-evils-of-the-reposeective-abstraction-layer

Nhưng nếu bạn có nhiều logic kinh doanh thì có. Đó là một ý tưởng tốt. Làm thế nào là thiết yếu để làm cho một lớp dịch vụ?


3
Tôi đã đọc bài đăng trên blog của Ayende nhiều lần và không thể lay chuyển được cảm giác rằng thiết kế của anh ấy (mà tôi đã đồng ý ở một thời điểm nào đó), trong khi đúng với tinh thần của YAGNI, gần như chắc chắn sẽ tốn nhiều thời gian hơn ngay cả khi trung hạn hơn chi phí để thiết lập sự trừu tượng của các lớp ở nơi đầu tiên. Tôi tự hỏi liệu anh ấy đã thay đổi quan điểm của mình về việc kết hợp chặt chẽ giữa toàn bộ ứng dụng và NHibernate hay chưa, vì nó thậm chí còn phổ biến hơn đối với một ứng dụng để truy vấn nhiều nguồn dữ liệu SQL, NoQuery và API.
Ông Cochese

@LennyGodber vâng, tôi biết cảm giác của bạn IMO tốt hơn khi có lớp DAO / kho lưu trữ vì nó có nhiều ưu điểm hơn bất lợi vì như bạn đã nói rất phổ biến khi có nhiều nguồn dữ liệu
Jesus

-1

IMHO lớp Dịch vụ có thể được coi là một lớp giữa bộ điều khiển và lớp DAO. Lớp dịch vụ này chính xác là nơi chúng ta có thể thêm logic nghiệp vụ và thậm chí tạo một đối tượng trả về cụ thể cho những gì cần được hiển thị bởi khung nhìn.

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.