2011-10-01 37 views
5

Tôi chỉ đang học java và tôi gặp một số vấn đề. Ở đây chúng tôi có mẫu nhà máy đơn giản:Đăng ký nhà máy tự động

public class SomeFactory { 
    ... 
    public static void registerProduct(String name, Class<? extends IProduct > f) 
} 

public SomeProduct implements IProduct { 
    static { 
     SomeFactory.register("some product", SomeProduct.class); 
    } 
    ... 
} 

Tất cả các sản phẩm phải đăng ký tại nhà máy.

Nhưng trước khi sử dụng mã này, tất cả các lớp Sản phẩm phải được tải. Tôi có thể đặt Class.forName() ở đâu đó, ví dụ như trong chức năng chính. Nhưng tôi muốn tránh các loại tải thủ công như vậy. Tôi chỉ muốn thêm mới IProduct triển khai mà không cập nhật các phần khác (chẳng hạn như SomeFactory hoặc Main phương pháp, v.v.). Nhưng tôi tự hỏi, liệu có thể tự động tải một số lớp (được đánh dấu bằng chú thích chẳng hạn)?

P.S Tôi muốn thông báo rằng không có lớp nào khác sẽ được thêm vào lúc chạy, tất cả các triển khai IProduct đều được biết trước khi biên dịch.

UPD # 1 Cảm ơn bạn đã trả lời! Nhưng có thể tạo tệp thuộc tính được tạo tự động với IProduct trường hợp không? Tôi có nghĩa là nó có thể làm cho một số kịch bản xây dựng-thời gian (cho maven ví dụ) mà tạo ra tập tin tài sản hoặc mã loader? Có các giải pháp hoặc khung như vậy không?

UPD # 2 tôi hoàn thành với việc sử dụng Reflections library cung cấp thông tin thời gian chạy, bằng cách quét classpath lúc khởi động.

Trả lời

5

Điều này có thể, nhưng không dễ dàng. Nó sẽ cần phải quét tất cả các lớp trong classpath để xem chúng có chú thích hay thực hiện giao diện IProduct hay không. Xem How do you find all subclasses of a given class in Java? để có câu trả lời cho vấn đề như vậy.

Tôi sẽ giữ cho nó đơn giản và chỉ có một danh sách các lớp để tải, hoặc trong bản thân nhà máy, hoặc trong một tập tin bên ngoài (tập tin thuộc tính, ví dụ).

3
  1. Yêu cầu mỗi sản phẩm tự đăng ký, sử dụng một khối tĩnh như thế này:

    class MyProduct1{ 
    
        static{ 
         SomeFactory.register(this.getClass()); 
        } 
        .. 
        .. 
    } 
    
  2. Hồ sở hữu bên ngoài có thể theo dõi tất cả các sản phẩm.

  3. Phương pháp chính của bạn có thể phân tích danh sách Sản phẩm này và thực hiện Class.forName ("..").

Bằng cách này bạn sẽ không cần phải mã hóa bất kỳ sản phẩm cụ thể nào, chỉ cần tệp thuộc tính tiếp tục thay đổi. Ah! có thêm đăng ký bảo mật cũng sẽ là một điểm cộng.

Lưu ý: Tôi chỉ đề xuất một ý tưởng, I'vent thử nó bản thân mình :)

+6

thế nào là 'this.getClass() 'sẽ làm việc trong' tĩnh {} '... O_O? –

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