Động lực đằng sau chú thích @ImcellenceedBy trong Guice là gì?


10

Gần đây tôi đã đọc về @ImplementedBychú thích có sẵn trong Google Guice . Nó cho phép lập trình viên chỉ định một ràng buộc giữa một giao diện và việc thực hiện nó để sử dụng trong tương lai trong tiêm phụ thuộc. Đây là một ví dụ về ràng buộc chỉ trong thời gian .

Tôi khá quen với việc xác định các ràng buộc rõ ràng trong các mô-đun của mình, sử dụng cú pháp sau:

bind(SomeInterface.class).to(SomeInterfaceImplementation.class);

Theo tài liệu này, điều này tương đương với việc sử dụng @ImplementedBychú thích sau đây:

@ImplementedBy(SomeInterfaceImplementation.class)
public interface SomeInterface {
    //method declarations
}

Lợi ích duy nhất tôi có thể thấy ở đây là mã ngắn hơn một chút. Đồng thời, cách tiếp cận này có một nhược điểm được chỉ ra bởi cùng một tài liệu:

Sử dụng @ImplementedBycẩn thận; nó thêm một phụ thuộc thời gian biên dịch từ giao diện để thực hiện nó.

Sự phụ thuộc như vậy có thể không phải là một vấn đề trong nhiều trường hợp nhưng cá nhân tôi thấy nó là một mùi mã.

Những trường hợp sử dụng làm cho @ImplementedBychú thích có giá trị sử dụng?

Một cách có thể dường như là sử dụng nó trong mã của thư viện hoặc khung. Như được mô tả trong các tài liệu, chú thích có thể cung cấp một ràng buộc mặc định dễ dàng bị ghi đè bởi một tài liệu rõ ràng.

Nếu một loại nằm trong cả một bind()câu lệnh (như là đối số đầu tiên) và có @ImplementedBychú thích, thì bind()câu lệnh được sử dụng. Chú thích cho thấy một triển khai mặc định có thể được ghi đè bằng một ràng buộc.

Bằng cách này, với tư cách là nhà phát triển của một thư viện, tôi có thể cung cấp cho người dùng của mình một ràng buộc ngoài hộp có thể được tùy chỉnh ở đâu đó trong mã máy khách.

Đây có phải là lý do duy nhất để chú thích tồn tại? Hay là tôi đang thiếu thứ gì đó? Tôi có thể đạt được bất cứ điều gì bằng cách sử dụng nó trong mã chỉ là một ứng dụng chăm sóc một số logic nghiệp vụ và không phải là một thư viện / khung để được mở rộng?


2
Câu hỏi liên quan, có thể trùng lặp (mặc dù tiêu đề của bạn rõ ràng hơn): @ImcellenceedBy của Guice có xấu không?
Jeff Bowman hỗ trợ Monica

Không phải là một bản sao nghiêm ngặt, nhưng đã có một số cuộc thảo luận thú vị về vấn đề này tại đây: stackoverflow.com/questions/6197178/
Kẻ

Câu trả lời:


8

Tôi nghĩ rằng sự nguy hiểm ở đây là sử dụng chỉ các @ImplementedBychú thích. Được sử dụng một cách thích hợp, kết hợp với các bind()câu lệnh trong mô-đun của bạn và vv.

Có một triển khai mặc định là rất tốt để thử nghiệm; bạn không nhất thiết phải xác định rõ ràng một mũi tiêm giả mỗi khi bạn đang kiểm tra một lớp có nhiều phụ thuộc hoặc nếu bạn có một lớp mà nhiều thứ phụ thuộc vào (vì vậy bạn phải xác định một giả mỗi lần ).

Ví dụ: bạn có thể có một lớp:

@ImplementedBy(NoOpDataService.class)
interface DataService {
    Map<String, MyPOJO> getData();
}

Và sau đó NoOpDataServicelà:

class NoOpDataService implements DataService {
    @Override
    public Map<String, MyPOJO> getData() {
        return Collections.emptyMap();
    }
}

Rõ ràng, bạn sẽ không bao giờ sử dụng mã này trong mã thực tế của mình; trong mô-đun Guice của bạn, bạn sẽ liên kết một triển khai thực sự làm một cái gì đó. Nhưng tất cả các bài kiểm tra trên các lớp được tiêm DataServicekhông cần phải có ràng buộc giả nữa.

tl; dr Tôi đồng ý với bạn rằng việc các giao diện của bạn phụ thuộc vào việc triển khai của bạn có thể là mùi mã; nhưng nó cũng có thể loại bỏ mã soạn sẵn giúp kiểm tra dễ dàng hơn. Nó không phải là một tính năng khó thực hiện; và mặc dù có một số khả năng lạm dụng nhỏ, cuối cùng hậu quả không thể quá tệ (một dịch vụ bắt đầu bất ngờ) và sẽ không quá khó để khắc phục ngay cả khi điều đó xảy ra.


3
Thêm mã kiểm tra vào sản xuất?
Basilevs
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.