Good practice to edit objects "by reference"? - java

Let's say I've got a type called Superstar. Now I want to have a method that does some work and edits some properties of a Superstar object.
Here are two ways of how I could implement this. Way 1 would be the following:
private Superstar editSuperstar(Superstar superstar){
....
superstar.setEdited(true);
return superstar;
}
...
superstar = editSuperstar(superstar);
And way 2 would be this:
private void editSuperstar(Superstar superstar){
....
superstar.setEdited(true);
}
...
editSuperstar(superstar);
Which one of these two possible ways is considered "best practice"? The first one, or the second pseudo "by reference" one?

In your case, the second form is preferrable, as you directly change one of you superstar properties (edited). However, if you have a method that use a superstar object and returns an updated version of it (without changing the initial one) the first form will have my favor.
Finally, since both of this examples only use Superstar object, they should be member methods of the Superstar class.

Use way 2 unless you are creating a "builder" class where you intend to chain invocations. Ex:
MyClass c = (new MyClassBuilder()).setX(blah).setY(blah).build();

The first form is deceptive. It gives the impression that one object is being passed in, which is copied and the copy then altered and returned.
"Best practice" would be to use the first form, but to actually do what is implied (apply the change to a copy, which is then returned). Immutable objects should generally be preferred over mutable objects unless they are big chunky things that are expensive to copy, in which case, you should then favor the second form.

The problem you have here with first method is if you use it like that:
Superstar edited = editSuperstar(originalSuperstar);
This will also modify the originalSuperstar which is, in my opinion, counterintuitive...
Thus prefer the second one if you modify the passed object or the first one if you return a new copy of the object.
For this peculiar example you could simply add an edit method to the Superstar class...

The first form would be surprising for the API clients if you return the same instance having only changed some fields. One would expect to get a modified copy back without having the original instance changed.
So use the second form if you don't return a copy and use the first if you do (and think about making Superstar immutable in that case).

Related

Best Practice: Java attributes might be null

So I have a constructor with 5 different variables, where three of which might be null. It accepts user input and the user does not have to enter anything for three of the five attributes.
Therefore, if the user did not enter anything, the object is created using null for all missing values.
obj = new Object(String, null, null, null, String);
Now I am wondering what would be best practice to cope with this.
I can think of three different scenarios:
Deal with it only in the class using the constructor, i.e. always query whether the value is null (e.g. if(getSomeAttribute == null) { //do something }
Deal with it within the object class, i.e. always return some default value for each missing attribute instead of null
Deal with it within the object lcass, i.e. have helper-methods like isAttributeSet(), returning a boolean value indicating whether the attributes are set, that is: not null.
Although I have problems with the last two, as I think I might run into problems with default values, as sometimes it might hard to know if it is a default value; if I'd always check I could just as well check for null instead of inserting a default value first;
Same with the last one, if I have to check the helper-method, I could just as well check for null directly.
What my problem is with this situation, is that sometimes I might not be the one using the getter and setter methods; how should the one using it know there might be null attributes and which that are.
I know, I should document that within my object class, but still I am wondering if there is a "best practice" way to cope with this.
I believe it should be unusual to always check the documentary (or if there is none, the whole class) for something as simple as this.
Maybe I should not even start with null values within my constructor in the first place? But I think I would run into the same kinds of problems, anyway, so that would not really solve my problem
Read Bloch, Effective Java, 2nd ed. Item 2: "Consider a builder when faced with many constructor parameters."
Excellent advice in an excellent book.
Using a builder pattern would help with the constructor, however the main problem is to do with the design of the class - you want to be sure when you call a get/set method that it isn't one of the null/optional members.
You could use polymorphism to have two objects each with an interface that only exposes the getters and setters supported by the concrete implementation. This makes it impossible to call the wrong getters/setters and it is obvious what the intention is.

Is it better to chain method invocations or to introduce an intermediate variable?

E.g. 2 method invocations:
myMethod(getHtmlFileName());
or
String htmlFileName=getHtmlFileName();
myMethod(htmlFileName);
which is better way, exclude less typing in first case ?
If you are going to use a return value of a method in more than one place, storing it in a variable and using that variable in your code could be more practical, readable and easily debuggable rather than calling the method every time:
String htmlFileName = getHtmlFileName();
myMethod(htmlFileName);
....
myMethod(htmlFileName + "...");
The second approach would help you debug the return value of getHtmlFileName(), but other than that, neither approach is better than the other in an absolute sense. It's a matter of preference, and perhaps context, I would say. In this particular case I'd go for the first approach, but if you were combining several methods, I'd go for the second, for sake of readability, e.g.:
String first = firstMethod();
String second = secondMethod(first);
String third = thirdMethod(second);
rather than
thirdMethod(secondMethod(firstMethod()));
EDIT: As others have pointed out, if you're going to use the value in more than one place, then obviously you'd use the second approach and keep a reference to the value for later use.
It will probably depend on the context.
If you are going to use htmlFileName variable elsewhere in you code block you probably what to store it local variable like (especially true for some heavy method calls) :
String htmlFileName=getHtmlFileName();
myMethod(htmlFileName);
if it is one-off call the
myMethod(getHtmlFileName());
is probably more elegant and easy to read.
If you use the getHtmlFileName() returned value later on, and if the returned value is fixed, you will want to use the first form, i.e. assign a local variable and reuse it, and thereby avoid redundant calls / object creations.
Otherwise (e.g. if you only call the getHtmlFileName method once, you will want to use the first form which is more concise, and which avoid a useless local variable assignment, but there is no real harm if you still use the second form (e.g. for debugging).

Number of parameters in method

I have Selenium test which fills a form. I have a method for it but this method has overgrown in terms of number of parameters -
newMerchantPage.addEditMerchant(merchantDomain, merchantName,
merchantCategory, true, merchantDescription, merchantNotes,
merchantTags, true, true, false, false, merchantTitle,
additionalDescription, merchantHeading, dummyCouponLink, true);
There are only Strings and boolean.
I was thinking to use collection and then iterate through collection in called method to do some more processing. Though yet not sure if this is the way to go about. Any recommendations?
MODIFIED METHOD:
After implementing couple of sugggestions my method (of a different method) call looks like -
ContactPage contactPage = new ContactPage(driver);
setContactFormData();
contactPage.setName(name).setEmailAddress(emailAddress).setSubject(subject).setM‌ ​essage(message);
contactPage.submitContactForm(contactPage);
submitContactForm in turn calls different utility methods. How bad does it look? Especially the last line (method call on object and same object being passed as argument) ?
One common approach is to wrap the parameters in a class. This class could then provide set-methods which return this to allow for a nice chaining. (See ProcessBuilder for a good example.)
Example:
MerchantData data = new MerchantData(); // initialize with sensible defaults
data.setDomain("example.com")
.setName("Some Name")
.setTags("tag1, tag2);
newMerchantPage.addEditMerchant(data);
I'm assuming that you are using Selenium server (or RC).
The suggestions for wrapping the data up into a Merchant class are all good and make sense, especially from pure Java coding point of view.
However, your main point of concern here in Selenium is the form you are filling, rather that the merchant domain object.
Maybe you could then break your method up into smaller methods such as
openMerchantForm(...)
typeNameInMerchantForm(...)
chooseMerchantCategory(...)
and so on, depending on what type of control is being set on the form. That will reflect the behaviour you are testing rather than setting the domain objects directly etc.
Hope that helps.
Maybe - write a class Merchant, create an instance with the method value and pass the instance instead?
newMerchantPage(Merchant merchant);
The advantage: you can keep the test parameters in files and do something like:
Merchant merchant = new Merchant();
merchant.populate(File testdata, int record);
Have you considered making a class that is if the parameters you specify belong to something same,then pass the object as the parameter.

What is the best practice to modify an object passed to a method

After passing an object into a method, I would like to change one of its fields. What's the best practice to do this task in Java?
Simple answer
As stated in other answers, you can simply call the setter method.
More philosophical answer
Generally, it can be dangerous to mutate objects in a scope other than that in which they were created:
http://en.wikipedia.org/wiki/Functional_programming
That said, there are often times where you simply want to encapsulate bits of logic in the same logical scope where you would want to modify values of an object passed in. So the rule I would use is that as long as all calling code is fully aware of such mutations, you can call the setter method on the object (and you should create a setter method if you don't have one) in the method to which you're passing the object.
In general, if you call a function that mutates parameters from multiple places in your codebase, you will find that it becomes increasingly error prone, which is why functional programming pays off.
So, the moral of the story is: if your caller(s) are fully aware of such mutations, you could change the value in your method, but in general you should try to avoid it and instead change it in the scope in which it was created (or create a copy).
Be aware of the fact that even if the object is passed as final it still can be changed. You just can't reassign the variable, which normally is desired for an (input/)output parameter.
Taking Jigar Joshis example:
public void increasePersonAgeByOneMonth(final Person p ){
p = new Person(); //this won't work, which is ok since otherwise the parameter itself would not be changed by the next method
p.setAge(((p.getAge()*12.0) + 1)/12.0); //ok
}

Dropping objects on the floor

I'm creating a cell editor, but I've done (and seen) this in other code. I'm creating an object and then dropping it on the floor like this:
ButtonCellEditor buttonColumn = new ButtonCellEditor(table, 2);
This class takes the table and sets a TableColumnModel and custom cell renderers to it. Then, the method ends and I don't reference the buttonColumn object anymore.
So, is there a difference between doing the above and doing this (which also works)?
new ButtonCellEditor(table, 2);
Anything really wrong with doing this?
You shouldn't have unused variables in your code, that makes it less clear. Also, a constructor is (as its name states) a method for initialize the object, this in your case is not done.
I suggest you to have a static method instead:
ButtonCellEditor.niceNameHere(table, 2);
The only case I can think in which a constructor would be adequate is when it takes params to initialize itself and then perform some actions later, but not for doing the action inside and this is not like yours.
There's nothing wrong with either of those way of creating a ButtonCellEditor. However, if you later want to reference that object, with method two you have no way of doing so. With method 1 you can at least say buttonColumn.method().
No tangible difference, as far as I know.
Nothing wrong either -- I would prefer shorter form, if the only reason really is to get side effects of constructing the object (which is not necessarily a very good API design in itself, IMO, but that's irrelevant here).
There is no real difference between the two cases. In the second case an anonymous variable will be created that will be normally garbage collected. The second case will also save you some typing and is somewhat more readable. A reader may expect to find a reference at the created object (if you choose the first version) and be surprised if he doesn't find one.
In any case, a static method may be more suitable for such cases.
they are the same, but a comment about why you are doing it might be in order. otherwise someone might come along and delete it, thinking it is a no-op without investigating.
you could also be more explict and call
table.getColumn(2).setCellEditor(new ButtonCellEditor());

Categories

Resources