2012-01-19 32 views
25

Tôi đã làm việc/thấy một vài dự án ứng dụng web mùa xuân-ngủ đông có nhiều giao diện vì có các lớp dao và dịch vụ thực tế.Tại sao luôn có giao diện implementaion đơn trong các lớp dịch vụ và dao?

Tôi luôn luôn nghĩ rằng hai là những lý do chính cho việc tổ chức các giao diện thực hiện duy nhất:

  1. mùa xuân có thể dây thực hiện thực tế là phụ thuộc trong một lớp nhất định (loose coupling)

    public class Person { 
        @Autowired 
        private Address address; 
    
        @Autowired 
        private AccountDetail accountDetail; 
    
        public Person(Address address, AccountDetail accountDetail) 
        { // constructor 
    
  2. Trong khi kiểm tra đơn vị, tôi có thể tạo các lớp mô phỏng và kiểm tra một lớp riêng biệt.

    Address mockedAddress = mock(Address); 
    AccountDetail mockedAccountDetail = mock(AccountDetail); 
    Person underTestPerson = new Person(mockedAddress, mockedAccountDetail); 
    // unit test follows 
    

Nhưng, của cuối năm, tôi nhận ra rằng:

mùa xuân có thể dây lớp thực hiện cụ thể như phụ thuộc:

public class Person { 

@Autowired 
private AddressImpl address; 

@Autowired 
private AccountDetailImpl accountDetail; 

public Person(AddressImpl address, AccountDetailImpl accountDetail) { 
// constructor 

khung Mock như EasyMock có thể thử các lớp bê tông cũng

AddressImpl mockedAddress = mock(AddressImpl); 
AccountDetailImpl mockedAccountDetail = mock(AccountDetailImpl); 
Person underTestPerson = new Person(mockedAddress, mockedAccountDetail); 
// unit test follows 

Ngoài ra, theo một cuộc thảo luận this, tôi nghĩ tóm tắt là trong một ứng dụng duy nhất, các giao diện chủ yếu được lạm dụng có thể là do quy ước hoặc thói quen. Chúng thường có ý nghĩa tốt nhất trong trường hợp chúng ta đang giao tiếp với một ứng dụng khác, ví dụ slf4j được nhiều ứng dụng trên khắp thế giới sử dụng. Trong một ứng dụng duy nhất, một lớp gần như là một trừu tượng như một giao diện. Vì vậy, câu hỏi của tôi là tại sao chúng ta vẫn cần Giao diện và sau đó có các triển khai đơn lẻ như các lớp * ServiceImpl và * DaoImpl và tăng kích thước cơ sở mã không cần thiết của chúng ta một cách không cần thiết. Có vấn đề gì trong các lớp bê tông chế nhạo mà tôi không biết. Bất cứ khi nào tôi đã thảo luận điều này với các đồng đội của tôi, chỉ có câu trả lời tôi nhận được là triển khai dịch vụ và các lớp dao dựa trên giao diện là THE DESIGN DESIGN sau đây - họ đề cập đến các thực hành tốt nhất mùa xuân, OOP, DDD, v.v. vẫn không nhận được một lý do thực dụng đằng sau có quá nhiều giao diện trong một ứng dụng riêng biệt.

+2

Về câu trả lời bạn nhận được - Tôi không thấy cách người ta có thể gọi DDD là lý do để ném giao diện trước mỗi đối tượng. DDD không liên quan gì đến điều đó. Ngay cả OOP cũng là một sự biện minh tồi tệ. Nếu bạn có những thứ như L, I và D của SOLID, họ chỉ xác định cách bạn nên thiết kế các trừu tượng như giao diện và những gì bạn nên sử dụng chúng, không phải là * bạn nên sử dụng chúng mọi lúc *. Vì vậy, như bạn đã nói, tôi đoán tất cả đều tập hợp thành "thực hành tốt nhất mùa xuân" hoặc chỉ những người làm điều đó trong thói quen. – guillaume31

Trả lời

14

Có nhiều lợi thế hơn cho giao diện - Như trong proxy. Nếu lớp của bạn thực hiện một giao diện, các proxy động JDK sẽ được sử dụng theo mặc định cho AOP. Nếu bạn sử dụng trực tiếp triển khai, bạn sẽ bị buộc phải sử dụng proxy CGLIB bằng cách thực hiện proxy-target-class = true. Những yêu cầu thao tác mã byte không giống như các proxy JDK.

đọc here để biết thêm về điều này.

Đọc một cuộc thảo luận khác tại what reasons are there to use interfaces (Java EE or Spring and JPA) để biết thêm thông tin.

14

Đó là một chủ đề rất gây tranh cãi. Tóm lại, không có gì - ít nhất là cho bạn, nhà phát triển.

Trong thế giới EJB2, giao diện Trang chủ và Từ xa là bắt buộc và chính xác vì lý do @AravindA đề cập: proxy. An ninh, truy cập từ xa, tổng hợp, vv tất cả có thể được gói trong một proxy, và cung cấp các dịch vụ được yêu cầu nghiêm ngặt trong thư viện chuẩn (như trong DynamicProxy).

Bây giờ chúng tôi có javaassistcglib, Mùa xuân (Hibernate, EJB3 nếu bạn thích) hoàn toàn có khả năng thiết kế các lớp của bạn như các nhà phát triển khung thích. Vấn đề là, những gì họ làm là một điều rất khó chịu: họ thường yêu cầu bạn thêm một constructor không có tham số. — Chờ đã, tôi có các tham số ở đây? —Nevermind, chỉ cần thêm hàm tạo.

Vì vậy, các giao diện ở đây để duy trì sự tỉnh táo của bạn. Tuy nhiên, đó là lạ, một nhà xây dựng không có đối số cho một lớp học với các nhà xây dựng thích hợp không phải là một cái gì đó mà làm cho một cảm giác với tôi, phải không? Hóa ra (tôi nên đọc spec, tôi biết) rằng Spring tạo ra một tương đương chức năng của một giao diện ra khỏi lớp của bạn: một cá thể không có (hoặc bỏ qua) và tất cả các phương thức được ghi đè. Vì vậy, bạn có một trường hợp "thực", và một "giao diện giả", và giao diện giả làm gì, nó phục vụ tất cả các phép thuật bảo mật/giao dịch/từ xa cho bạn. Đẹp, nhưng khó hiểu, và trông giống như một lỗi nếu bạn không tách nó ra. Hơn nữa, nếu bạn tình cờ thực hiện một giao diện trong lớp học của bạn, (ít nhất một số phiên bản) Spring đột nhiên quyết định bạn sẽ chỉ proxy giao diện này, và ứng dụng không hoạt động vì không có lý do rõ ràng.

Vì vậy, cho đến nay lý do là, sự an toàn và sự tỉnh táo. Có những lý do tại sao nó là một thực hành tốt - nhưng từ bài viết của bạn, tôi thấy bạn đã đọc tất cả những điều đó. Lý do quan trọng nhất tôi có thể thấy hôm nay là chỉ số WTH/phút, đặc biệt nếu chúng ta đang nói về những người mới đến dự án của bạn.

Các vấn đề liên quan