2009-04-15 11 views
5

Jestem zaangażowany w ten projekt, w którym budujemy na bazie starszego kodu. Mam szczególną sytuację dotyczącą jednego dużego obiektu bean Java, który musi zostać przeniesiony za pomocą kabla. Więc moja pierwsza myśl była, aby to niezmienne i serializable rade .W ten punkt mam do czynienia z kilku trudnych wyborów: -Tworzenie niezmiennych obiektów z javabean

  1. Idealnie chcę jakiś sposób automatycznie generować niezmienna, serializable wersja tej klasy. Nie mam zakresu do refaktoryzacji lub zmienić tę klasę w jakikolwiek sposób, a ja naprawdę nie chciałbym mieć do skopiować wkleić klasy z inną nazwą o ?

  2. Zakładając, że dałem się na 1 czyli I rzeczywiście zdecydował się powielać kod ogromnej klasy JavaBeans, nadal będzie w nieprzyjemnej sytuacji od konieczności pisania konstruktora z niektórych parametrów 20-25 aby uczynić niezmienną klasą. jaki jest lepszy sposób na unieruchomienie klasy innej niż wstrzyknięcie konstruktora?

Dzięki i Pozdrawiam,

+0

To jest bardzo dobre pytanie. Dopóki nie masz zduplikowanej niezmiennej klasy - nie wydaje się, żeby to naprawdę dobry sposób na rozwiązanie tego problemu. Użyłem metody skutecznie niezmiennej! – Fortyrunner

Odpowiedz

4

Aby uczynić go naprawdę niezmienne, trzeba zainicjować członków w czasie budowy.

Jednym ze sposobów (i nie mówię, że to jest piękne!), Aby to zrobić i uniknąć ogromnej listy parametrów w konstruktorze, jest posiadanie zmiennego typu, który ma te same właściwości. Ustaw właściwości na zmiennym typie po jednym za pomocą "setters", a następnie przekazuj zmienny obiekt do konstruktora typu niezmiennego jako pojedynczy argument. Obiekt niezmienny następnie kopiuje właściwości od zmiennego źródła do własnych (final) elementów.

Możesz również rozważyć "efektywną niezmienność". To znaczy, mimo że niezmienność nie jest wymuszana przez system, używasz praktyk kodowania, które wyraźnie oddzielają fazę inicjalizacji od fazy użytkowania. Mimo wszystko niezmienność nie jest wymagana do serializacji.

Możesz zrobić kolejny krok, tworząc ukrytą w pakiecie powłokę dla interfejsu, która nie eksponuje właściwości implementacji. Opakowanie implementuje tylko metody w interfejsie, poprzez delegowanie do "rzeczywistej" implementacji. Ustawień i pobierających z implementacji nie ma w opakowaniu. Spowoduje to zatrzymanie klientów od prostego rzucania z interfejsu do klasy implementacji i manipulowania właściwościami.

+0

możesz dodać przykład kodu dla każdego ze scenariuszy, próbuję zrozumieć i mieć trudności. – Rachel

1

Właściwości 20-25 nie są zbyt duże, by można je było jednorazowo wykorzystać, szczególnie jeśli używasz edytora o przyzwoitym poziomie.

Jeśli masz już zmienną instancję podczas konstruowania niezmiennej wersji, po prostu przekaż ją do konstruktora.

Jeśli chcesz być naprawdę zła hacky, użyj java.beans stworzyć serialisable Map na zmienny klasy lub podklasy wykonawczego Externalizable. Alternatywnie można użyć serializacji java.beans XML (XML może być wysłany przez serializację Java ...).

0

Krok 1: Utwórz nową klasę i nadać mu zmienne instancji z dokładnie takich samych nazwach jak zmiennych instancji swoim „wielkim java fasoli obiektu”. Ta nowa klasa nie powinna mieć seterów (ale tylko pobierających), aby stała się niezmienna.

Krok 2 Use Apache Commons BeanUtils.copyProperties skopiować wszystkie właściwości (czyli zmiennych instancji) od „dużego obiektu java fasoli” do nowego obiektu.

0

Kilka pomysłów:

Chronione ustawiaczy i metody fabryczne Można zdefiniować fasoli z zabezpieczonych metod dostępowych i w tym samym opakowaniu, klasa fabryki, które ma wszystkie parametry i wywołuje te ustawiające. Fasola jest niezmienna poza tym opakowaniem. Aby to wymusić, należy zapieczętować słoik, aby użytkownicy końcowi nie mogli tworzyć nowych klas w tym samym pakiecie.

Uwaga: Można wykorzystać moje adnotacje JavaDude Bean do tworzenia prostsza: http://code.google.com/p/javadude/wiki/Annotations

Na przykład:

@Bean(writer=Access.PROTECTED, // all setXXX methods will be protected 
    properties={ 
     @Property(name="name"), 
     @Property(name="age", type=int.class) 
    }) 
public class Person extends PersonGen { 
} 

Tworzenie pobierające i konstruktor w Eclipse

Eclipse kilka fajnych narzędzi, aby zrobić to szybko:

  1. Tworzenie klasy fasoli
  2. Dodaj pola, które chcesz
  3. prawym przyciskiem myszy w oknie edytora
  4. Wybierz source-> Generowanie pobierające i ustawiające
  5. naciśnij „Wybierz pobierające przycisk”
  6. Prasa ok
  7. prawym przyciskiem myszy w oknie edytora
  8. Wybierz source-> Generowanie konstruktorów z pól
  9. Pic k oraz zamówić pola, które mają w konstruktorze
  10. Naciśnij OK

niezmienność Dekorator

Innym pomysłem jest, aby zdefiniować Bean z pobierające i ustawiające (można użyć powyższej techniki, ale to ustawiające), możesz utworzyć klasę opakowania, która zawiera tylko moduły pobierające.

1

Co o prostym interfejsie cotaining czytać tylko te pobierające?

Jeśli klasa komponentu bean jest twoja, pozwól jej w prosty sposób zaimplementować interfejs i użyj interfejsu po utworzeniu.

Jeśli nie masz kontroli nad klasą komponentu bean, możesz również utworzyć interfejs pobierający i zaimplementować go, tworząc proxy dla interfejsu pobierającego, korzystając z procedury obsługi wywołania delegującej wszystkie wywołania metod do komponentu bean.

Powiązane problemy