Zaimplementowałem kilka aplikacji Java, jak dotąd tylko aplikacje desktopowe. Wolę używać niezmiennych obiektów do przekazywania danych w aplikacji zamiast używać obiektów z mutatorami (ustawiającymi i pobierającymi ), zwanymi również JavaBeans.
Ale w świecie Javy wydaje się, że znacznie częściej używa się JavaBeans i nie rozumiem, dlaczego powinienem ich używać. Osobiście kod wygląda lepiej, jeśli zajmuje się tylko niezmiennymi obiektami, zamiast stale mutować stan.
Niezmienne obiekty są również zalecane w pozycji 15: Minimalizuj zmienność , Efektywna Java 2ed .
Gdybym miał obiekt Person
zaimplementowany jako JavaBean , wyglądałoby to tak:
public class Person {
private String name;
private Place birthPlace;
public Person() {}
public setName(String name) {
this.name = name;
}
public setBirthPlace(Place birthPlace) {
this.birthPlace = birthPlace;
}
public String getName() {
return name;
}
public Place getBirthPlace() {
return birthPlace;
}
}
I to samo Person
zaimplementowane jako niezmienny obiekt:
public class Person {
private final String name;
private final Place birthPlace;
public Person(String name, Place birthPlace) {
this.name = name;
this.birthPlace = birthPlace;
}
public String getName() {
return name;
}
public Place getBirthPlace() {
return birthPlace;
}
}
Lub bliżej litery struct
C:
public class Person {
public final String name;
public final Place birthPlace;
public Person(String name, Place birthPlace) {
this.name = name;
this.birthPlace = birthPlace;
}
}
Mogłem również mieć metody pobierające w niezmiennym obiekcie, aby ukryć szczegóły implementacji. Ale ponieważ używam go tylko jako struct
, wolę pominąć „pobierające” i zachować prostotę.
Po prostu nie rozumiem, dlaczego lepiej jest używać JavaBeans, lub czy mogę i powinienem kontynuować korzystanie z moich niezmiennych POJO?
Wydaje się, że wiele bibliotek Java ma lepszą obsługę JavaBeans, ale może z czasem popularniejsze staje się większe wsparcie dla niezmiennych POJO?
źródło
Odpowiedzi:
Preferuj JavaBeans, kiedy
Preferuj niezmienne POJO, kiedy
źródło
Zaskoczyło mnie, że słowo Wątek nie pojawiło się nigdzie w tej dyskusji.
Jedną z głównych zalet niezmiennych klas jest to, że są one z natury bardziej bezpieczne dla wątków ze względu na brak mutowalnego, wspólnego stanu.
Nie tylko ułatwia to kodowanie, ale także daje dwie korzyści związane z wydajnością jako efekt uboczny:
Mniejsza potrzeba synchronizacji.
Większy zakres stosowania zmiennych końcowych, co może ułatwić późniejsze optymalizacje kompilatora.
Naprawdę staram się przejść do niezmiennych obiektów, a nie klas w stylu JavaBean. Ujawnianie wnętrzności obiektów za pomocą metod pobierających i ustawiających prawdopodobnie nie powinno być domyślnym wyborem.
źródło
To zależy od tego, co próbujesz zrobić. Jeśli pracujesz z trwałą warstwą i pobierasz jakiś wiersz z bazy danych do POJO i chcesz zmienić właściwość i zapisać ją z powrotem, użycie stylu JavaBean byłoby lepsze, zwłaszcza jeśli masz wiele właściwości.
Weź pod uwagę, że twoja osoba ma wiele pól, takich jak imię, drugie imię, nazwisko, data urodzenia, członkowie rodziny, wykształcenie, praca, wynagrodzenie itp.
Tak się składa, że ta osoba jest kobietą, która właśnie wyszła za mąż i zgodziła się na zmianę nazwiska, a Ty musisz zaktualizować bazę danych.
Jeśli używasz niezmiennego POJO, pobierasz reprezentujący ją obiekt Person, a następnie tworzysz nowy obiekt Person, do którego przekazujesz wszystkie właściwości, których nie zmieniłeś, takimi, jakie są, oraz nowe nazwisko i zapisujesz je.
Gdyby to był komponent Java, możesz po prostu zrobić setLastName () i zapisać go.
To „Minimalizuj zmienność”, a nie „nigdy nie używaj zmiennych obiektów”. Niektóre sytuacje działają lepiej z obiektami zmiennymi, naprawdę twoim zadaniem jest zdecydować, czy uczynienie obiektu zmiennym będzie lepiej pasować do twojego programu, czy nie. Nie powinieneś zawsze mówić „musisz używać niezmiennych obiektów”, zamiast tego sprawdź, ile klas możesz uczynić niezmiennymi, zanim zaczniesz robić sobie krzywdę.
źródło
Podsumowując inne odpowiedzi myślę, że:
get(id): Client
asave(MutableClient)
będąc MutableClientem, potomkiem Client.Gdyby istniał punkt pośredni (tworzenie, ustawianie właściwości, dokonywanie niezmienności), być może struktury zachęcałyby bardziej do niezmiennego podejścia.
W każdym razie proponuję myśleć o obiektach niezmiennych jako „tylko do odczytu Java Beans”, podkreślając, że jeśli jesteś dobrym chłopcem i nie dotykasz tej niebezpiecznej metody setProperty, wszystko będzie dobrze.
źródło
Od Java 7 możesz mieć niezmienne ziarna, najlepsze z obu światów. Użyj adnotacji @ConstructorProperties w swoim konstruktorze.
public class Person { private final String name; private final Place birthPlace; @ConstructorProperties({"name", "birthPlace"}) public Person(String name, Place birthPlace) { this.name = name; this.birthPlace = birthPlace; } public String getName() { return name; } public Place getBirthPlace() { return birthPlace; } }
źródło
Szczerze mówiąc, nie sądzę, aby niezmienne przedmioty stały się tak popularne.
Widzę zalety, ale frameworki takie jak Hibernate i Spring są obecnie bardzo modne (i nie bez powodu) i naprawdę działają najlepiej z fasolą.
Więc nie sądzę, że niezmienność jest zła, ale z pewnością ograniczyłaby twoje opcje integracji z obecnymi frameworkami.
EDYTOWAĆ Komentarze skłaniają mnie do nieco wyjaśnienia mojej odpowiedzi.
Z pewnością istnieją obszary problemowe, w których niezmienność jest bardzo użyteczna i rzeczywiście jest używana. Ale myślę, że obecna wartość domyślna wydaje się być zmienna, ponieważ jest to najbardziej oczekiwane i niezmienne tylko wtedy, gdy ma to wyraźną przewagę.
I chociaż rzeczywiście jest możliwe użycie konstruktorów z argumentami w Spring, wydaje się, że jest to zamierzone jako sposób na użycie starego i / lub zewnętrznego kodu z pięknym, zupełnie nowym kodem Springa. Przynajmniej to, co wyłowiłem z dokumentacji.
źródło
X
iY
odnosisz się do tego samego obiektu i chcesz zmienićX.something
, możesz zachować tożsamość X i zmienićY.something
, lub pozostawićY.something
niezmienioną i zmienić tożsamość X, ale nie można zachować tożsamości X i stanu Y podczas zmiany stan X.Niezmienne w zakresie programowania w Javie: coś, co raz stworzone, nigdy nie powinno mieć zmiany stanu, zarówno oczekiwanej, jak i nieoczekiwanej!
Ta technika jest przydatna w programowaniu obronnym, w którym inna jednostka nie może wywołać zmiany stanu.
Przykłady, w których nie spodziewasz się zmiany: Systemy zewnętrzne (jedno- lub wielowątkowe), które uzyskują odniesienie z Twojej warstwy i działają na obiekcie i świadomie lub nieświadomie go zmieniają. Teraz może to być POJO, kolekcja lub odniesienie do obiektu i nie spodziewasz się zmiany w tym lub chcesz chronić dane. Zdecydowanie uczyniłbyś przedmiot niezmiennym jako technika obronna
Przykłady, w których spodziewasz się zmiany: Naprawdę nie potrzebujesz niezmienności, ponieważ przeszkadza to we właściwych procedurach programowania.
źródło