Có phải là một thực tế xấu khi có một giao diện để xác định các hằng số?


40

Tôi đang viết một tập hợp các lớp kiểm tra Junit trong Java. Có một số hằng, ví dụ các chuỗi mà tôi sẽ cần trong các lớp kiểm tra khác nhau. Tôi đang suy nghĩ về một giao diện xác định chúng và mọi lớp kiểm tra sẽ thực hiện nó.

Những lợi ích tôi thấy có:

  • dễ dàng truy cập vào hằng số: MY_CONSTANTthay vìThatClass.MY_CONSTANT
  • mỗi hằng số chỉ được xác định một lần

Cách tiếp cận này là một thực hành tốt hay xấu? Tôi cảm thấy như lạm dụng khái niệm giao diện một chút.

Bạn có thể trả lời chung về giao diện / hằng, nhưng cũng về các bài kiểm tra đơn vị nếu có điều gì đó đặc biệt về nó.


Câu trả lời cho "Đó là một thực tiễn tồi khi có giao diện xác định X?", Là X bất cứ điều gì không phải là "chữ ký phương thức", gần như luôn luôn là "Có".
T. Sar - Tái lập Monica

Câu trả lời:


79

Joshua Bloch khuyên chống lại điều này trong cuốn sách Java hiệu quả :

Một lớp sử dụng một số hằng số bên trong là một chi tiết triển khai. Việc triển khai một giao diện không đổi khiến chi tiết triển khai này bị rò rỉ vào các lớp API đã xuất. Nó không có kết quả đối với người dùng của một lớp mà lớp thực hiện một giao diện không đổi. Trong thực tế, nó thậm chí có thể nhầm lẫn họ. Tồi tệ hơn, nó thể hiện một cam kết: nếu trong một bản phát hành trong tương lai, lớp được sửa đổi để nó không còn cần sử dụng các hằng số, thì nó vẫn phải thực hiện giao diện để đảm bảo khả năng tương thích nhị phân.

Bạn có thể có được hiệu ứng tương tự với một lớp bình thường xác định các hằng, và sau đó sử dụng import static com.example.Constants.*;


13

Trong trường hợp của chúng tôi, chúng tôi đang làm điều này bởi vì các giá trị của các hằng số thể hiện một hợp đồng cho các trạng thái kết thúc rằng việc triển khai dịch vụ là bắt buộc để cung cấp. Việc đặt các hằng số này trong giao diện chỉ định các trạng thái kết thúc như là một phần của hợp đồng và nếu bất kỳ triển khai nào của giao diện không sử dụng chúng, thì nó sẽ không hoạt động.

Các hằng số SOMETIMES là chi tiết thực hiện. Họ không có. Như thường lệ, một kỹ sư cần sử dụng bộ não của mình để quyết định phải làm gì và không dựa vào mô hình quét hoặc thực hành.


7

Tôi không nghĩ rằng đó là một điều tốt để có giao diện duy nhất cho hằng số.

Nhưng nếu một giao diện xác định hành vi (các phương thức triển khai các lớp nên thực hiện), có các hằng số thì không sao. Nếu nó "rò rỉ chi tiết của một số người triển khai" vào API, thì đó là vì nó nên như vậy. Họ cũng đang rò rỉ rằng người thực hiện thực hiện các phương pháp foo và bar.

Lấy ví dụ giao diện java.awt.Trans minh bạch. Nó có các hằng số OPAQUE, BITMASK và TRANSLUCENT nhưng cũng có phương thức getTrans minh bạch ().

Nếu nhà thiết kế đặt các hằng số đó vào đó, thì anh ta / cô ta nghĩ rằng nó sẽ đủ ổn định để trở thành một phần của giao diện, như getTrans minh ().


2

Hãy nghĩ rằng đó là một quan điểm chủ yếu phổ biến ở những nơi mà thiết kế theo hợp đồng là phổ biến.
Giao diện là hợp đồng. Đặt các hằng số trong các giao diện có nghĩa là mọi lớp tuân theo hợp đồng đều đồng ý với giá trị / khái niệm được xác định bởi hằng số.


1
giao diện là hợp đồng công cộng. GIÁ TRỊ không đổi là mối quan tâm riêng tư, giao diện công cộng tối đa nên để lộ tên của họ. Đó là tốt nhất để lại cho một lớp trừu tượng.
jwenting

Các trường hợp tại điểm: javax.naming.Context, javax.ims.Session và hàng trăm giao diện như vậy ...
CMR

2
@jwenting Ngoài ra, một giao diện công cộng "at most expose their names", mà không để lộ các giá trị?
CMR

điều đó phụ thuộc vào ngôn ngữ lập trình mà tôi đoán. Trong trường hợp của Java, không.
jwenting

2

Một công ty tôi làm việc tại đã sử dụng nặng của giao diện nhập khẩu 1 hằng số. Tôi không cảm thấy bất kỳ tác hại nào đến từ nó.

Câu hỏi bạn nên tự đặt ra là, việc đặt tên cho bạn quan trọng như thế nào? Trong trường hợp các hằng số, đó thực sự là một lớp hoạt động như. Nếu bạn có hàng ngàn hằng số, bạn có thể không muốn tất cả các hằng số đó luôn có sẵn.

Điều thú vị về giao diện là nó mang lại cho bạn lợi ích khi làm việc theo cách nào đó - mang lại tất cả các không gian tên bạn cần, hoặc không có cái nào trong số chúng (và truy cập chúng một cách rõ ràng, với MyInterface.CONSTANT). Khá nhiều điều tương tự như import static MyInterface.*, nhưng một chút rõ ràng hơn.


1: Nếu bạn không quen thuộc với Java, tôi không có nghĩa là importtừ khóa, tôi chỉ có nghĩa là mang vào thông quaimplements MyConstantsInterface


1

Tôi đến từ một nền tảng chủ yếu bị ảnh hưởng chủ yếu bởi 'cách Ada' và '.Net cách.' Tôi sẽ nói không, rằng có lẽ không phải là tốt nhất để khai báo hằng trong các giao diện. Đó là kỹ thuật không được phép trong c #.

Lý do tôi nói không là giao diện là một dạng hợp đồng xác định hành vi, không phải trạng thái hoặc cấu trúc. Một hằng số ngụ ý một số loại trạng thái (nguyên thủy), hoặc một khía cạnh của trạng thái (tổng hợp hoặc tổng hợp).

Tôi có thể đánh giá cao sự thôi thúc đưa ra các giá trị mặc định và các giá trị được xác định trước cho mọi người thực hiện giao diện, nhưng có lẽ trạng thái mặc định sẽ được mô tả tốt hơn trong một đối tượng hoặc mẫu trừu tượng hoặc giá trị, trong đó các mặc định sẽ có ít nhất là bối cảnh tối thiểu.

Để có hướng dẫn kỹ thuật hơn: download.oracle.com/javase/1.5.0/docs/guide/lingu/static-import.html


Thêm nhiều liên kết đề cập đến Nhập tĩnh (1.5): 1. Wikipedia 2. Tài liệu tham khảo Oracle @Justinc
Abhijeet

1
So when should you use static import? Very sparingly! Only use it when you'd otherwise be tempted to declare local copies of constants, or to abuse inheritance (the Constant Interface Antipattern). In other words, use it when you require frequent access to static members from one or two classes. If you overuse the static import feature, it can make your program unreadable and unmaintainable, polluting its namespace with all the static members you import. Tham khảo từ Tài liệu Oracle
Abhijeet

1

Không, đó không phải là một thực hành xấu chung.

Vấn đề là các hằng số như bất kỳ vật phẩm nào khác phải được giới thiệu theo các quy tắc về tầm nhìn tối thiểu và mức độ trừu tượng thích hợp.

Sử dụng cú pháp chỉ bởi vì bạn có thể là vấn đề thực sự.

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.