2010-05-24 49 views
10

Tôi có một giao diện ProductService với phương thức findByCriteria. Phương pháp này có danh sách dài các tham số có thể vô hiệu hóa, như productName, maxCost, minCost, producer v.v.Có điều gì xấu trong việc khai báo lớp lồng nhau bên trong giao diện trong java không?

Tôi đã tái cấu trúc phương pháp này bằng cách giới thiệu Parameter Object. Tôi tạo ra lớp SearchCriteria và bây giờ phương pháp chữ ký trông như thế này:

findByCriteria (SearchCriteria criteria) 

tôi nghĩ rằng trường hợp của SearchCriteria chỉ được tạo ra bởi người gọi phương pháp và chỉ được sử dụng bên trong findByCriteria phương pháp, ví dụ:

void processRequest() { 
    SearchCriteria criteria = new SearchCriteria() 
            .withMaxCost (maxCost) 
            ....... 
            .withProducer (producer); 

    List<Product> products = productService.findByCriteria (criteria); 
    .... 
} 

List<Product> findByCriteria(SearchCriteria criteria) { 
    return doSmthAndReturnResult(criteria.getMaxCost(), criteria.getProducer());  
} 

Vì vậy, tôi không muốn tạo một lớp công khai riêng biệt cho SearchCriteria và đặt nó bên trong ProductServiceInterface:

public interface ProductService { 
    List<Product> findByCriteria (SearchCriteria criteria); 

    static class SearchCriteria { 
     ... 
    } 
} 

Có điều gì xấu với giao diện này không? Bạn đặt SearchCriteria ở đâu?

+3

Bạn không cần đánh dấu SearchCriteria là tĩnh, tất cả các loại thành viên của giao diện hoàn toàn tĩnh (và công khai). – Oak

Trả lời

3

Tôi nghĩ nó trông đẹp. Nó rõ ràng báo hiệu rằng SearchCriteria được thiết kế để sử dụng với ProductService s cụ thể.

Tuy nhiên, một số người cho rằng các lớp lồng nhau có vẻ kỳ lạ và cho rằng đây sẽ là thiết kế quá mức và phạm vi gói đủ tốt trong hầu hết các trường hợp kể cả trường hợp này.

2

Nó không phải là xấu, và có thể hữu ích nếu bạn muốn một nhóm chặt chẽ hơn giữa các giao diện và một số đối tượng tiện ích, như so sánh. (Tôi đã thực hiện chính xác cùng một giao diện và các lớp bên trong cung cấp các trình so sánh hữu ích so sánh các giao diện của giao diện.)

. tên giao diện (hoặc sử dụng một nhập tĩnh), nhưng một IDE tốt sẽ chăm sóc điều này cho bạn (nhưng mã có thể được xếp chồng với các khai báo Interface.SomeClass, trông không đẹp như vậy.)

Tuy nhiên, cụ thể trường hợp, SearchCriteria trông không được kết hợp chặt chẽ với giao diện, vì vậy nó có thể dễ sử dụng hơn như một lớp gói thông thường.

2

Tôi sẽ khuyến khích bạn sử dụng các lớp học khi bạn có các phương pháp có thể đòi hỏi nhiều hoặc ít đối số không có giá trị; nó mang lại cho bạn khả năng để cung cấp bất cứ điều gì bạn cần mà không cần phải gọi một phương thức như:

someMethod("foo", null, null, null, null, null, null, ..., "bar"); 

Sử dụng mecanism như vậy, các cuộc gọi phương pháp sẽ là một cái gì đó như:

someMethod(new ObjParam().setFoo("foo").setBar("bar")); 

Phương pháp thứ hai là tiêu hao và có thể tái sử dụng (không có một tấn phương pháp ghi đè). Và tôi không nói ở đây rằng phương pháp ghi đè là xấu! Khá ngược lại. Tuy nhiên với nhiều đối số tùy chọn, tôi muốn cuộc gọi thứ hai.

Đối với các lớp bên trong, họ là hữu ích vào những thời điểm, nhưng cá nhân tôi làm theo các hướng dẫn sau:

  1. cố gắng sử dụng các lớp bên trong chỉ khi lớp bên trong nên tin (ví dụ: trong trường hợp của một phong tục Thực thi LinkedList, lớp Node là một lớp riêng và do đó là lớp bên trong.)
  2. thường chỉ khi lớp không thể sử dụng lại được và được sử dụng chủ yếu trong một nhóm nhỏ (rất) mà tôi sẽ làm cho lớp bên trong là
  3. "cha mẹ" và lớp bên trong trở nên đủ lớn; sau đó cả hai lớp được cung cấp tệp nguồn Java của riêng chúng để có thể đọc được, trừ khi lớp bên trong phải là riêng tư như đối với điểm đầu tiên.

Hãy nhớ rằng, bên trong lớp học hay không, trình biên dịch Java sẽ tạo một lớp cho mỗi lớp. Bạn càng sử dụng chúng, ít mã của bạn sẽ được đọc. Bạn có thể quyết định xem họ có hợp lý hay không ...

0

Tôi e rằng tôi muốn bỏ phiếu cho điều xấu. Khá tệ, bạn có thể làm những điều tồi tệ hơn ...

Để đơn giản, một lớp học chỉ nên nhắm vào một trách nhiệm. Việc triển khai ProductService của bạn có định nghĩa lớp tiêu chí bên trong nó, vì vậy khi bạn đi lang thang qua mã, bạn phải biết phần nào của tệp mà bạn đang sử dụng.

Quan trọng hơn, việc tách biệt làm cho mã của các thực thể có liên quan đơn giản hơn rõ ràng hơn. Đối với tôi, điều này ghi đè tất cả các mối quan tâm khác (ah, ngoài các mã được chính xác của khóa học). Tôi tìm thấy sự đơn giản & explictness là hữu ích nhất khi nói đến việc giữ lại mái tóc của tôi, hoặc ít nhất là của những người sẽ duy trì công cụ ...

+0

Không có định nghĩa lớp tiêu chí bên trong lớp ProductServiceImpl. Nó được định nghĩa bên trong giao diện ProductService. – Roman

+0

Hmm, tôi đoán đọc thêm các câu trả lời - về vấn đề các lớp bên trong - so với mã ban đầu của bạn. Lớp tiêu chí của bạn nằm trong chữ ký dịch vụ công cộng, do đó khách hàng điền vào. Hầu hết những người tôi biết sẽ viết điều này như là một lớp công khai thường xuyên - nó có một sử dụng công cộng sau khi tất cả. – StripLight

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