2011-10-01 14 views
5

Po prostu uczę się java i napotykam pewne problemy. Tu mamy prosty wzór fabryczny:Automatyczna rejestracja fabryczna

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

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

Wszystkie produkty powinny zarejestrować się w fabryce.

Jednak przed użyciem tego kodu należy załadować wszystkie klasy produktów. Mogę umieścić gdzieś Class.forName(), na przykład w głównej funkcji. Ale chcę uniknąć tego rodzaju ręcznego ładowania klas. Chcę tylko dodać nowe implementacje IProduct , bez aktualizowania innych części (takich jak metody SomeFactory lub Main itd.). Ale zastanawiam się, czy możliwe jest automatyczne ładowanie niektórych klas (na przykład z adnotacją)?

P.S Chciałbym zauważyć, że żadne inne klasy nie zostaną dodane w czasie wykonywania, wszystkie implementacje IProduct są znane przed kompilacją.

UPD # 1 Dziękujemy za odpowiedź! Ale czy można wygenerować automatycznie wygenerowany plik właściwości z instancjami IProduct? Chodzi mi o to, czy można utworzyć skrypt czasu budowania (na przykład dla maven), który generuje plik właściwości lub kod programu ładującego? Czy istnieją takie rozwiązania lub ramy?

UPD # 2 skończyłem z użyciem Reflections library który zawiera informacje run-time, skanując ścieżki klasy podczas uruchamiania.

Odpowiedz

5

Jest to możliwe, ale niełatwe. Musi przeskanować wszystkie klasy w ścieżce klas, aby sprawdzić, czy mają adnotację lub implementować interfejs IProduct. Aby uzyskać odpowiedzi na taki problem, patrz How do you find all subclasses of a given class in Java?.

Chciałbym zachować proste i mieć listę klas do załadowania, albo w samej fabryce, albo w zewnętrznym pliku (na przykład plik właściwości).

3
  1. Czy każdy produkt zarejestrować się za pomocą statycznego bloku tak:

    class MyProduct1{ 
    
        static{ 
         SomeFactory.register(this.getClass()); 
        } 
        .. 
        .. 
    } 
    
  2. zewnętrznego pliku nieruchomość może śledzić wszystkich produktów.

  3. Twoja główna metoda może przeanalizować tę listę produktów i wykonać Class.forName ("..").

W ten sposób nie trzeba kodować żadnego konkretnego produktu, tylko plik właściwości wciąż się zmienia. Ach! tak dodanie rejestracji bezpieczeństwa będzie również dodatkowym atutem.

Uwaga: Ja tylko proponuje pomysł I'vent próbowałem to sam :)

+6

Jak to 'this.getClass()' zadziała w '' {} static ... O_O? –