He implementado algunas aplicaciones Java ahora, solo aplicaciones de escritorio hasta ahora. Prefiero usar objetos inmutables para pasar los datos en la aplicación en lugar de usar objetos con mutadores (setters y getters ), también llamados JavaBeans.
Pero en el mundo de Java, parece ser mucho más común usar JavaBeans, y no puedo entender por qué debería usarlos en su lugar. Personalmente, el código se ve mejor si solo trata con objetos inmutables en lugar de mutar el estado todo el tiempo.
Los objetos inmutables también se recomiendan en el artículo 15: Minimizar la mutabilidad , Java 2ed efectivo .
Si tengo un objeto Person
implementado como JavaBean , se vería así:
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;
}
}
Y lo mismo Person
implementado como un objeto inmutable :
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;
}
}
Or closer to an struct
in C:
public class Person {
public final String name;
public final Place birthPlace;
public Person(String name, Place birthPlace) {
this.name = name;
this.birthPlace = birthPlace;
}
}
I could also have getters in the immutable object to hide the implementation details. But since I only use it as a struct
I prefer to skip the "getters", and keep it simple.
Simply, I don't understand why it's better to use JavaBeans, or if I can and should keep going with my immutable POJOs?
Many of the Java libraries seem to have better support for JavaBeans, but maybe more support for immutable POJOs gets more popular over time?
fuente
Respuestas:
Prefer JavaBeans When
Prefer Immutable POJOs When
fuente
I was surprised that the word Thread did not appear anywhere in this discussion.
One of the main benefits of immutable classes is that they are inherently more thread safe due to no mutable, shared state.
Not only does this make your coding easier, it'll also give you two performance benefits as a side effect:
Less need for synchronization.
More scope for using final variables, which can facilitate subsequent compiler optimisations.
I am really trying to move towards immutable objects rather than JavaBean style classes. Exposing the guts of objects via getters and setters should probably not be the default choice.
fuente
Well it depends on what you're trying to do. If your working with a persistent layer, and you fetch some row from the database into a POJO, and you want to change a property and save it back, using JavaBean style would be better, especially if you have a lot of properties.
Consider that your person, has a lot of fields like, first, middle, last name, date of birth, family members, education, job, salary etc.
And that Person happens to be a female that just got married and accepted to have her last name changed, and you need to update the database.
If you're using immutable POJO, you fetch a Person object representing her, then you create a new Person object to which you pass all the properties that you didn't change as they are, and the new last name, and save it.
If it were a Java bean you can just do setLastName() and save it.
It's 'Minimize mutability' not 'never use mutable objects'. Some situations work better with mutable objects, it's really your job to decide if making an object mutable will better fit your program or not. You shouldn't always say 'must use immutable objects', instead see how many classes you can make immutable before you start hurting yourself.
fuente
Summarizing other answers I think that:
get(id): Client
andsave(MutableClient)
, being MutableClient some descendant of Client.If there were an intermediate point (create, set properties, make inmutable) maybe frameworks would encourage more an inmutable approach.
Anyway I suggest thinking in inmutable objects as "read only Java Beans" stressing the point that if you are a good boy and don't touch that dangerous setProperty method all will be fine.
fuente
From Java 7 you can have immutable beans, the best of both worlds. Use the annotation @ConstructorProperties on your constructor.
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; } }
fuente
I don't think immutable objects will get all that popular, to be honest.
I do see the advantages, but frameworks like Hibernate and Spring are currently very much in vogue (and for a good reason too), and they really work best with beans.
So I don't think immutability is bad, but it would certainly limit your integration options with current frameworks.
EDIT The comments prompt me to clarify my answer a bit.
There most certainly are problem areas where immutability is very useful, and is indeed used. But I think the current default seems to be mutable as that is what is mostly expected, and only immutable if that has a clear advantage.
And though it is indeed possible to use constructors with arguments in Spring it seems to be intended as a way to use legacy and/or third party code with you beautiful brand-new Spring code. At least that's what I picked up from the documentation.
fuente
X
andY
refer to the same object and one wants to changeX.something
, one may keep the identity of X and changeY.something
, or leaveY.something
unchanged and change the identity of X, but one cannot keep the identity of X and the state of Y while changing the state of X.Immutable in terms of programming in Java : Something that once created should never have change of state , both expected or unexpected!
This technique is useful in defensive programming where another entity cannot induce change in the state.
Examples where you don't expect change : External systems(single or multi threaded) which gets reference from your layer and operates upon the object and knowingly or unknowingly change it. Now it could be a POJO or an collection or an object reference and you don't expect a change in it or you want to protect the data. You would definitely make the object immutable as defensive technique
Examples where you expect change : Really don't need immutability as it will obstruct in right programming procedures.
fuente