Setter returning this vs builder - java

I was wondering, when constructing an object, is there any difference between a setter returning this:
public User withId(String name) {
this.name = name;
return this;
}
and a builder (for example one which is generated by Builder Generator plugin for IDEA)?
My first impression is that a setter returning this is much better:
it uses less code - no extra class for builder, no build() call at the end of object construction.
it reads better:
new User().withName("Some Name").withAge(30);
vs
User.UserBuilder.anUserBuilder().withName("Some Name").withAge(30).build();
Then why to use builder at all? Is there anything I am missing?

The crucial thing to understand is the concept of an immutable type.
Let's say I have this code:
public class UnitedStates {
private static final List<String> STATE_NAMES =
Arrays.asList("Washington", "Ohio", "Oregon", "... etc");
public static List<String> getStateNames() {
return STATE_NAMES:
}
}
Looks good, right?
Nope! This code is broken! See, I could do this, whilst twirling my moustache and wielding a monocle:
UnitedStates.getStateNames().set(0, "Turtlia"); // Haha, suck it washington!!
and that will work. Now for ALL callers, apparently there's some state called Turtlia. Washington? Wha? Nowhere to be found.
The problem is that Arrays.asList returns a mutable object: There are methods you can invoke on this object that change it.
Such objects cannot be shared with code you don't trust, and given that you don't remember every line you ever wrote, you can't trust yourself in a month or two, so, you basically can't trust anybody. If you want to write this code properly, all you had to do is use List.of instead of Arrays.asList, because List.of produces an immutable object. It has zero methods that change it. It seems like it has methods (it has a set method!), but try invoking it. It won't work, you'll get an exception, and crucially, the list does not change. It is in fact impossible to do so. Fortunately, String is also immutable.
Immutables are much easier to reason about, and can be shared freely with whatever you like without copying.
So, want your own immutable? Great - but apparently the only way to make one, is to have a constructor where all values are set and that's it - immutable types cannot have set methods, because that would mutate them.
If you have a lot of fields, especially if those fields have the same or similar types, this gets annoying fast. Quick!
new Bridge("Golden Gate", 1280, 1937, 2737);
when was it built? How long is it? What's the length of the largest span?
Uhhhhhhh..... how about this instead:
newBridge()
.name("Golden Gate")
.longestSpan(1280)
.built(1937)
.length(2737)
.build();
sweet. Names! builders also let you build over time (by passing the builder around to different bits of code, each responsible for setting up their bits). But a bridgebuilder isn't a bridge, and each invoke of build() will make a new one, so you keep the general rules about immutability (a BridgeBuilder is not immutable, but any Bridge objects made by the build() method are.
If we try to do this with setters, it doesn't work. Bridges can't have setters. you can have 'withers', where you have set-like methods that create entirely new objects, but, calling these 'set' is misleading, and you create both a ton of garbage (rarely relevant, the GC is very good at collecting short lived objects), and intermediate senseless bridges:
Bridge goldenGate = Bridge.create().withName("Golden Gate").withLength(2737);
somewhere in the middle of that operation you have a bridge named 'Golden Gate', with no length at all.
In fact, the builder can decide to not let you build() bridge with no length, by checking for that and throwing if you try. This process of invoking one method at a time can't do that. At best it can mark a bridge instance as 'invalid', and any attempt to interact with it, short of calling .withX() methods on it, results in an exception, but that's more effort, and leads to a less discoverable API (the with methods are mixed up with the rest, and all the other methods appear to throw some state exception that is normally never relevant.. that feels icky).
THAT is why you need builders.
NB: Project Lombok's #Builder annotation gives you builders for no effort at all. All you'd have to write is:
import lombok.Value;
import lombok.Builder;
#Value #Builder
public class Bridge {
String name;
int built;
int length;
int span;
}
and lombok automatically takes care of the rest. You can just Bridge.builder().name("Golden Gate").span(1280).built(1937).length(2737).build();.

Builders are design patterns and are used to bring a clear structure to the code. They are also often used to create immutable class variables. You can also define preconditions when calling the build() method.

I think your question is better formulated like:
Shall we create a separate Builder class when implementing the Builder Pattern or shall we just keep returning the same instance?
According to the Head First Design Patterns:
Use the Builder Pattern to encapsulate the construction of a product
and allow it to be constructed in steps.
Hence, the Encapsulation is important point.
Let's now see the difference in the approaches you have provided in your original question. The main difference is the Design, of how you implement the Builder Pattern, i.e. how you keep building the object:
In the ObjecBuilder separate class approach, you keep returning the Builder object, and you only(!) return the finalized/built Object, after you have finalized building, and that's what better encapsulates creation process, as it's more consistent and structurally well designed approach, because you have a clearly separated two distinct phases:
1.1) Building the object;
1.2) Finalizing the building, and returning the built instance (this may give you the facility to have immutable built objects, if you eliminate setters).
In the example of just returning this from the same type, you still can modify it, which probably will lead to inconsistent and insecure design of the class.

It depends on the nature of your class. If your fields are not final (i.e. if the class can be mutable), then doing this:
new User().setEmail("alalal#gmail.com").setPassword("abcde");
or doing this:
User.newBuilder().withEmail("alalal#gmail.com").withPassowrd("abcde").build();
... changes nothing.
However, if your fields are supposed to be final (which generally speaking is to be preferred, in order to avoid unwanted modifications of the fields, when of course it is not necessary for them to be mutable), then the builder pattern guarantees you that your object will not be constructed until when all fields are set.
Of course, you may reach the same result exposing a single constructor with all the parameters:
public User(String email, String password);
... but when you have a large number of parameters it becomes more convenient and more readable to be able to see each of the sets you do before building the object.

One advantage of a Builder is you can use it to create an object without knowing its precise class - similar to how you could use a Factory. Imagine a case where you want to create a database connection, but the connection class differs between MySQL, PostgreSQL, DB2 or whatever - the builder could then choose and instantiate the correct implementation class, and you do not need to actually worry about it.
A setter function, of course, can not do this, because it requires an object to already be instantiated.

The key point is whether the intermediate object is a valid instance.
If new User() is a valid User, and new User().withName("Some Name") is a valid User, and new User().withName("Some Name").withAge(30) is a valid user, then by all means use your pattern.
However, is a User really valid if you've not provided a name and an age? Perhaps, perhaps not: it could be if there is a sensible default value for these, but names and ages can't really have default values.
The thing about a User.Builder is the intermediate result isn't a User: you set multiple fields, and only then build a User.

Related

Checking String parameters corresponding to field names

I'm heavily using Java.lang.Class.getField() method which requires a String variable as an argument. The problem I'm facing is when I change field names, that getField() refers to, Eclipse doesn't warn me that argument points nowhere (since it's String) and I end up having methods working improperly unnoticed.
So far I can see two ways out. It's either using try-catch blocks around every getField() call and running application to see what will be the next line to throw an exception. Fix it and watch out for the next exception. Or it's using Find/Replace feature every time I change a field name to manually look for the String value and replace it. Is there a more friendly (i.e. automatic) way to update String parameters in such cases?
Maybe there's a method (which I fail to find) that accepts a full field path as a non-String argument and returns a Field object? Something like turnToFieldObject(car.speed) returning Field object corresponding to speed field so that Eclipse would automatically check if there's such a field car.speed.
PS
First of all, thank you for your replies.
I can see that a lot of you, guys, suggest that I'm using reflection too much. That's why I feel I need to add extra explanation and would be glad to hear suggestions as well.
I'm doing a research about modeling social evolution and I need the entities to evolve new features that they don't have at the start. And it seemed to me that adding new fields to represent some evolutional changes is better understanding wise than adding new elements to arrays or collections. And the task suggests I shouldn't be able to know what feature will be evolved. That's why I rely so heavily on reflection.
AFAIK, there is no such method. You pass a reference (if it's an object) or value (if it's primitive); all data about the variables that they were originally assigned to is not available at runtime.
This is the huge downside of using reflection, and if you're "heavily" using this feature in such way, you're probably doing something wrong. Why not access the field directly, using getters and setters?
Don't get me wrong, reflection has its uses (for example, when you want to scan for fields with certain annotations and inject their values), but if you're referencing fields or methods by their name using a simple string, you could just as well access fields or methods directly. It implies that you know the field beforehand. If it's private, there is probably a reason why it's encapsulated. You're losing the content assist and refactoring possibilities by overusing reflection.
If you're modeling social evolution, I'd go with a more flexible solution. Adding new fields at runtime is (near?) impossible, so you are basically forced to implement a new class for each entity and create a new object each time the entity "evolves". That's why I suggest you to go with one of these solutions:
Use Map<String, Object> to store entities' properties. This is a very flexible solution which will allow you easily add and remove "fields" at the cost of losing their type data. Checking if the entity has a certain property will be a cheap contains call.
If you really want to stick to a million custom classes, use interfaces with getters and setters in addition to fields. For example, convert private String name to interface Named { String getName(); void setName(String name); }. This is much easier to refactor and does not rely on reflection. A class can implement as many interfaces as you want, so this is pretty much like the field solution, except it allows you to create custom getters/setters with extra logic if desperately needed. And determining if entity has a certain property is a entity instanceof MyInterface call, which is still cheaper than reflection.
I would suggest writing a method that use to get your fields supply it a string and then if the exception is thrown notify whatever needs to be notified that it was not valid and if the exception isn't caught return the field.
Although I do agree with the above that reflection should not be used heavily.

Return copies of private data rather than references

In the astonishing book "Java the Good Parts" the author gives some code that returns a copy of an object within its getter method (to be used with an well-encapsulated field) and then states:
This approach, which tries to return copies of private data
rather than references to that private data, is generally a good idea
Why is that so? I thought a goal of encapsulation was to make sure that nobody can actually alter private members. So why would I write something like this
private someType fieldName = new someType();
...
while defining its getter like this (assuming that there is some sort of copy-constructor)
someType getSomething()
{
return new someType(fieldName);
}
From what I know now, I mean before you guys pop in is:
that this makes sense in so far that it services garbage collection, since this approach doesn't maintain references to the actual object.
it also may be understandable from an inner-class perspective, from which any method could alter any field accesable via the reference.
But I don't suspect the two reasons for doing so to be what's really beyond that issue.
When types are mutable, it's often useful to return a copy so that a client can't fundamentally modify your data, at least without telling you about it. Consider:
public class Person {
private Date dateOfBirth;
public Date getDateOfBirth() {
return dateOfBirth;
}
public void setDateOfBirth(Date dateOfBirth) {
// Do some validation, e.g. that it's after 1800
this.dateOfBirth = dateOfBirth;
}
}
That looks okay, right? But what about:
Person person = new Person();
person.setDateOfBirth(new Date()); // Now... fine.
// Aha! Modify the Date to a very long time ago. Now anyone else
// using the Person will be messed up...
person.getDateOfBirth().setTime(Long.MIN_VALUE);
If getDateOfBirth returns a copy instead, then any changes the caller makes to the Date object that the return value refers to will be irrelevant to anyone else. The Person object is still valid, because it only has a valid date. Of course, this should be documented so that whoever wrote the above code would expect it not to affect the Person object, due to a copy being returned.
A better solution than all of this copying is to favour immutable types, however - when you've got a reference to an immutable object, you can share that as widely as you like, knowing that no-one can change its state under your feet.
The idea is that the getter lets you view the state of the object without being able to modify it (since you'll be modifying a copy, and not the original).
If you call :
someType property = someObj.getSomething();
and then
property.setSomeSubProperty(someValue);
This would only change the copy of someType, and not the original someType stored within someObj.
If the class that contains the getSomething() method is mutable, it may have a setSomething(someType value) method, and using that method would be the acceptable way to modify that property.
Good answers already come up, but let me come up with other examples and references
Best source to explain would be a Effective Java by Josh Bloch. There are at least 2 chapters about immutability and defensive copies.
To make it short:
In Java you pass everything by a reference (I know that it's oversimplified, but that's not the point) and many classes are mutable. Hence direct assignment of private field with external object is not really safe, as value underneath can change at any point of time from outside of the object, breaking the encapsulation.
Accessor methods are the essence of breaking the encapsulation. In the most common implementation, you just make the field public and, as mentioned above, you allow anyone to change underlying objects, if they allow to do so. Best example are collections IMHO. If you return any default Java collection, anyone can add something to it, remove element or even purge it. If your logic depends on the state or you are writing multithreaded app it's the easiest way to get a race condition, something we really don't want to have.
So a good practice is either
returning the deep copy of an object (e.g. Guava copy collection methods)
returning a view on a object (e.g. Collections class and its methods)
using immutable objects (easiest of 'em all)
cloning or other funky business
Each of those have some cost related to them. Copying/cloning takes time and memory. Views are not fully safe, as underlying implementation may change at any point of time, immutable objects does not allow modification and are hard to implement in legacy systems, etc It's up to you to find balance, but we're always happy to help :)
Last thing, it's also a good practice to do a defensive copy in constructor/setter of passed in mutable parameter, for exactly same reason. If someone would add elements to collection that we've made final in constructor, that would be quite stupid, c's we're not preserving state, which we obviously wanted. So again, in constructor don't do just a simple initialization if you're not controlling what has been passed in (and even if you do, it may be a good idea to copy)
I prefer collections as an example, as they are easier to reason on how to make copy/how they change, however StringBuilder and Date mentioned in other answers, really show that it's not only issue of collections. So best answer is: Remember, final is your best friend. Use it often, from the very beginning, and never trust mutable strangers!
Because there is no such thing as "private data", there is in reality only data that you can't reach and data you can't change.
Suppose that fieldName is defined as StringBuilder fieldName. There's nothing you can do to a StringBuilder that will prevent someone that has access to it from modifying it. On the other hand, if it is defined as string fieldName, then (absent some truly evil reflection) there is no chance of someone else changing it.
So, it's an expensive substitute for immutability. Better yet is to use a wrapper that only allows access to the properties and actions you want to make available.

Best Practice - HashMap instead of list of parameters, good idea ?

Hi Stackoverflow community,
I am working on some code where a list of optional criterias criterias is submitted to my dao.
Method signature contains the list of +/- 10 parameters, which I really don't like and want to reformat.
Plus I would like to avoid having to refactor all method signatures from different layers just because I add/remove a criteria
List searchParams(String name, Long countryCode, ...){
...
}
would become
List searchParams(HashMap<String,Object> map) {
BeanUtils.populate(this,map);
...
}
I am a bit worried that this happen to because kind of a bad practice, because I give up control of what is passed in the map to give me that flexibility ? So my question is if I am on the right path proceeding that way?
When I encounter situations like this, I tend to create a Params class, and pass that around. The benefits are that:
unlike when using a Map, you can have meaningful getters/settings, proper validation etc;
it's type-safe and self-describing (meaning it's easy to find out the available parameters and their types).
you can add new parameters without having to refactor any intermediate layers.
You could define a new class to hold/handle your set of parameters, so you get a bit more control than a HashMap would give you. Annoying to write, or at least tedious, but seems like a better balance between flexibility & control.
You could look at your parameters and see if you can wrap them as a logical group into an object. For example a name an a country code could be a person object
public Person {
private String name;
private String countryCode;
}
Then you will just be passing this object down and can use getters to get the data out which should be easier to read and maintain than needing to know all the keys for the HashMap on multiple layers.
The only case where using a map is appropriate is when you are designing a factory, and you need to pass different kinds of parameters to different classes being created. In all other cases, a solution with a specialized parameter info class would be preferred.
For an example of where passing a map is appropriate, look at the DriverManager.getConnection method: this method needs to pass parameters to constructors of driver-specific implementations of the Connection being created, so it wraps a map into Properties, and lets the user pass it through to the driver-specific connection. Note that DriverManager does not have another solution that would be future-proof.
I would strongly discourage using a map in all other cases: the added flexibility shifts error detection from compile-time to run-time, which has a strong potential of multiplying your headache beyond belief.

Using an untyped wrapper class around objects stored in XML, is this bad?

class MyThing {
protected HashMap<String,Object> fields;
protected MyThing(HashMap<String,Object> newFields){
fields.putAll(newFields);
}
protected Object get(String key){
return fields.get(key);
}
}
Now a little background. I am using this class as a super class to a bunch of different classes which represent objects from an XML file. This is basically an implementation of an API wrapper and I am using this as an adapter between the parsed XML from an API and a database. Casting is delegated to the caller of the get method. If the subclasses need to do something when they are created or when they return a variable, they just call super and then manipulate what gets returned afterwards. eg.:
class Event extends MyThing {
public Event(HashMap<String,Object> newFields){
super(newFields);
// Removes anything after an # symbol in returned data
Pattern p = Pattern.compile("\\#.*$");
Matcher m = p.matcher((String)fields.get("id"));
boolean result = m.find();
if (result)
fields.put("id", m.replaceFirst(""));
}
}
public Object get(String key){
Object obj = super(key);
if (key.equals("name")){
return "Mr./Mrs. " + ((String)obj);
}
}
}
The reason I feel like I should do this is so I don't have to write getId, getName, getWhatever methods for every single subclass just because they have different attributes. It would save time and it is pretty self explanatory.
Now this is obviously "unJavalike" and more like a ducktyped language way of doing things, but is there a logical reason why I should absolutely not be doing this?
If you're going to this level of complexity and mucking up your object model just because you don't want to have getters and setters, do it in Groovy instead.
Groovy is a duck typed dynamic language on the JVM that accepts 98% of valid Java code, so you already know most of the language (you don't lose functionality)...there are "more idiomatic" ways of doing things, but you can pick those up with time. It also already has a built in XmlSlurper, which probably does most of what you're trying to do anyway.
As for the "reasons why you shouldn't", you're introducing all types of maintainability concerns.
New classes will always have to derive from the base class.
They will have to implement a constructor that always calls a base constructor
They will have to override get() [which you're basically using to encapsulate your getters and setters anyway, why not just add that method and delegate to those other methods] and write specific logic which is likely to degrade with time.
Why shouldn't you? It'll work, right? Sure. But it's poor engineering in that you're either creating a maintenance nightmare, or reinventing the wheel and likely to do it wrong.
Obviously, it's not type safe.
Future maintainers won't know what the types are supposed to be and will get generally confused as to why you're not using POJOs.
Instead of constant time, space complexity and performance you have the characteristics of a HashMap.
It become very difficult to write non-trivial getters/setters in future.
Most data binding systems are designed to work with POJOs/Beans (JAXB, JPA, Jackson, etc).
I'm sure there are more, but this will do. Try using some proper OXM libraries and you'll be much better off.

Considering object encapsulation, should getters return an immutable property?

When a getter returns a property, such as returning a List of other related objects, should that list and it's objects be immutable to prevent code outside of the class, changing the state of those objects, without the main parent object knowing?
For example if a Contact object, has a getDetails getter, which returns a List of ContactDetails objects, then any code calling that getter:
can remove ContactDetail objects from that list without the Contact object knowing of it.
can change each ContactDetail object without the Contact object knowing of it.
So what should we do here? Should we just trust the calling code and return easily mutable objects, or go the hard way and make a immutable class for each mutable class?
It's a matter of whether you should be "defensive" in your code. If you're the (sole) user of your class and you trust yourself then by all means no need for immutability. However, if this code needs to work no matter what, or you don't trust your user, then make everything that is externalized immutable.
That said, most properties I create are mutable. An occasional user botches this up, but then again it's his/her fault, since it is clearly documented that mutation should not occur via mutable objects received via getters.
It depends on the context. If the list is intended to be mutable, there is no point in cluttering up the API of the main class with methods to mutate it when List has a perfectly good API of its own.
However, if the main class can't cope with mutations, then you'll need to return an immutable list - and the entries in the list may also need to be immutable themselves.
Don't forget, though, that you can return a custom List implementation that knows how to respond safely to mutation requests, whether by firing events or by performing any required actions directly. In fact, this is a classic example of a good time to use an inner class.
If you have control of the calling code then what matters most is that the choice you make is documented well in all the right places.
Joshua Bloch in his excellent "Effective Java" book says that you should ALWAYS make defensive copies when returning something like this. That may be a little extreme, especially if the ContactDetails objects are not Cloneable, but it's always the safe way. If in doubt always favour code safety over performance - unless profiling has shown that the cloneing is a real performance bottleneck.
There are actually several levels of protection you can add. You can simply return the member, which is essentially giving any other class access to the internals of your class. Very unsafe, but in fairness widely done. It will also cause you trouble later if you want to change the internals so that the ContactDetails are stored in a Set. You can return a newly-created list with references to the same objects in the internal list. This is safer - another class can't remove or add to the list, but it can modify the existing objects. Thirdly return a newly created list with copies of the ContactDetails objects. That's the safe way, but can be expensive.
I would do this a better way. Don't return a list at all - instead return an iterator over a list. That way you don't have to create a new list (List has a method to get an iterator) but the external class can't modify the list. It can still modify the items, unless you write your own iterator that clones the elements as needed. If you later switch to using another collection internally it can still return an iterator, so no external changes are needed.
In the particular case of a Collection, List, Set, or Map in Java, it is easy to return an immutable view to the class using return Collections.unmodifiableList(list);
Of course, if it is possible that the backing-data will still be modified then you need to make a full copy of the list.
Depends on the context, really. But generally, yes, one should write as defensive code as possible (returning array copies, returning readonly wrappers around collections etc.). In any case, it should be clearly documented.
I used to return a read-only version of the list, or at least, a copy. But each object contained in the list must be editable, unless they are immutable by design.
I think you'll find that it's very rare for every gettable to be immutable.
What you could do is to fire events when a property is changed within such objects. Not a perfect solution either.
Documentation is probably the most pragmatic solution ;)
Your first imperative should be to follow the Law of Demeter or ‘Tell don't ask’; tell the object instance what to do e.g.
contact.print( printer ) ; // or
contact.show( new Dialog() ) ; // or
contactList.findByName( searchName ).print( printer ) ;
Object-oriented code tells objects to do things. Procedural code gets information then acts on that information. Asking an object to reveal the details of its internals breaks encapsulation, it is procedural code, not sound OO programming and as Will has already said it is a flawed design.
If you follow the Law of Demeter approach any change in the state of an object occurs through its defined interface, therefore side-effects are known and controlled. Your problem goes away.
When I was starting out I was still heavily under the influence of HIDE YOUR DATA OO PRINCIPALS LOL. I would sit and ponder what would happen if somebody changed the state of one of the objects exposed by a property. Should I make them read only for external callers? Should I not expose them at all?
Collections brought out these anxieties to the extreme. I mean, somebody could remove all the objects in the collection while I'm not looking!
I eventually realized that if your objects' hold such tight dependencies on their externally visible properties and their types that, if somebody touches them in a bad place you go boom, your architecture is flawed.
There are valid reasons to make your external properties readonly and their types immutable. But that is the corner case, not the typical one, imho.
First of all, setters and getters are an indication of bad OO. Generally the idea of OO is you ask the object to do something for you. Setting and getting is the opposite. Sun should have figured out some other way to implement Java beans so that people wouldn't pick up this pattern and think it's "Correct".
Secondly, each object you have should be a world in itself--generally, if you are going to use setters and getters they should return fairly safe independent objects. Those objects may or may not be immutable because they are just first-class objects. The other possibility is that they return native types which are always immutable. So saying "Should setters and getters return something immutable" doesn't make too much sense.
As for making immutable objects themselves, you should virtually always make the members inside your object final unless you have a strong reason not to (Final should have been the default, "mutable" should be a keyword that overrides that default). This implies that wherever possible, objects will be immutable.
As for predefined quasi-object things you might pass around, I recommend you wrap stuff like collections and groups of values that go together into their own classes with their own methods. I virtually never pass around an unprotected collection simply because you aren't giving any guidance/help on how it's used where the use of a well-designed object should be obvious. Safety is also a factor since allowing someone access to a collection inside your class makes it virtually impossible to ensure that the class will always be valid.

Categories