Guava Optional. How to use the correct - java

I have a class
private class TouchCommand {
private int action;
private int x;
private int y;
...
When the command is executed, it is necessary to verify the field values ​​- null / not null, and depending on it to produce longitudinal action. I want to use Options from Google Guava.
Which solution is right?
this:
public boolean executeCommand() {
Optional<Integer> optionalAction = Optional.fromNullable(action);
...
or:
private class TouchCommand {
private Optional<Integer> action;
private Optional<Integer> x;
private Optional<Integer> y;
...
Given that the call to parseAction may also return a null (or absent):
TouchCommand touchCommand = new TouchCommand();
touchCommand.mAction = parseAction(xmlParser.getAttributeValue(namespace, "action"));
...
Questions:
whether or not to do so: the method parseAction (and similar) returns Optional ?
whether or not to do so: the field of class objects Optional ?
whether or not to do so: when checking the fields of the class (assuming that they can be null) to convert them into objects Optional ?
Thx.

Guava contributor here...
Any or all of these things are fine, but some of them may be overkill.
Generally, as discussed in this StackOverflow answer, Optional is primarily used for two things: to make it clearer what you would've meant by null, and in method return values to make sure the caller takes care of the "absent" case (which it's easier to forget with null). We certainly don't advocate replacing every nullable value with an Optional everywhere in your code -- we certainly don't do that within Guava itself!
A lot of this will have to be your decision -- there's no universal rule, it's a relatively subjective judgement, and I don't have enough context to determine what I'd do in your place -- but based on what context you've provided, I'd consider making the methods return Optional, but probably wouldn't change any of the other fields or anything.

Related

Representing optional properties in a class

I have an Java class with a number of properties, some of which are optional.
In the example below the properties linkerNumber, linkerStatus, and linkerPressure are optional and represent a physical object that may or may not be attached to the device.
Right now I have mixed primitive and non-primitive types since linkerPressure is optional but flow, inputPressure, and outputPressure are required.
Should I:
Change all properties to be non-primitive for the sake of uniformity?
Mix primitive and non-primitive type to match what is/isn't required?
Represent linker values as their own object with a special null class (Null Object Pattern)?
My aversion to using the Null Object Pattern is that a separate linker object would not provide any additional functionality to me.
public class State {
private long serial;
private long received;
private String deviceId;
private String linkerNumber;
private String linkerStatus;
private Integer linkerPressure;
private int flow;
private int inputPressure;
private int outputPressure;
What is the best way to represent this data?
I would first think of the Builder pattern (if that is not already in place here), then I would wrap each optional parameter into an Optional from java.util (or guava if you are under java-8).
Thing is, even if you make them all Objects, the caller of getFlow for example (that will return an Integer) would probably not think of checking for null first and then acting on it, it will assume a non-null value. How many times do you check the return types of Objects againt null?
But getting an Optional<Integer> (or OptionalInt) forces the caller to think and act accordingly. Just notice that Optional<T> is used mainly for return types, denoting a potentially missing value.
To stay in accordance to that you could have something like:
class State {
private Integer flow; // nullable
public Optional<Integer> getFlow(){
return Optional.ofNullable(flow);
}
}

Why would one use a `java.util.function.supplier`, when one can just call a method?

I saw some example of of using supplier interface at https://dzone.com/articles/supplier-interface.
My question is, if in the above example I could do something as easy as :
driveVehicle(new Vehicle());
driveVehicle(new Car());
Why would one want to use supplier interface, if all it does is call a method, without taking in any parameters.
Suppose you have parameters stored in database that you want to keep in constant all over your app
// Assume retrieveSystemParameter query database which allows to change parameters
public static String SYSTEM_PARAMETER = StaticUtilities.retrieveSystemParameter();
That value will be initialized once and won't change untill a redeployment. That being said, if instead you use a supplier :
public static Supplier<String> SYSTEM_PARAMETER_SUPPLIER = StaticUtilities::retrieveSystemParameter;
When you need the value somewhere you will call SYSTEM_PARAMETER_SUPPLIER.get() which will retrieve parameter in the database when needed - that way if you change a parameter in database, you won't have to redeploy.
As you can see, Suppliers are lazy. They do the work when you ask them to work (by calling .get()) - that may allow you some performance gain if you deal with them wisely. Sometimes you will call a method which expect a variable X passing in method retrieveX and then end up not needing X in the method because some conditions were not met. In that case you will lose performance as you will execute the code to retrieve X while a supplier that retrieve X would only execute it when calling .get and you would only do that call if the conditions were met.
Disclaimer : the system parameter constant is just the first example that came to my mind, but considering it query the database on each .get() you'd rather cache the parameter and have the cache call .get() at a specific interval.
I guess Optional might be perfect example. Consider the following snippet:
final Product firstProduct = Optional.ofNullable(product)
.orElse(productDao.findProductById(id));
final Product secondProduct = Optional.ofNullable(product)
.orElseGet(() -> productDao.findProductById(id));
You're getting a product that may be null. In order to determine firstProduct java will have to call expression in orElse method so no matter product is null or not you always have to determine value that will be returned in case product is null.
In order to determine secondProduct database doesn't have to be queried in case product is not null because you're passing a Supplier that will be called only if product is null.
Another example is when your method that accepts a supplier is not pure (i.e., it has side effect), and the side effect happens before calling the lambda, and the behaviour of the lambda is affected by the side effect.
Consider, for instance, this example:
public class TestClass {
private String field;
public String getField() {
return field;
}
public void method(Supplier<String> supplier) {
field = "This is";
System.out.println(supplier.get() + " a test");
}
public static void main(String[] args) {
TestClass c = new TestClass();
c.method(() -> c.getField());
}
}
Here, method() is not pure, as it changes the value of field, which is used later in the lambda (through calling the getField() method). As the lambda is called in place (i.e., when get() is called), calling getField() will happen after setting the field. In other words, method() accepts a Supplier<String> instead of a String in an attempt to let the clients safely call the getField() method.
Of course, having side effects should be avoided wherever possible, and this is just a toy example, but it shows a potential place where a supplier can be used.
Supplier adds one more level of indirection.
Given that "All problems in computer science can be solved by another level of indirection", it's likely that there are some problems that can be solved by using a Supplier.
Beware, however, of the corollary "...except for the problem of too many layers of indirection."
So, if there's no problem to solve, then Supplier is overkill and you should stick to directly invoking new.
Put differently: mistrust any "pattern" or "best practice" that doesn't start by explaining a problem (your question shows, you actually do mistrust, so just keep on asking this kind of questions).
I use it to avoid the unnecessary creation of additional states:
private Supplier<Boolean> detach = () -> false;
private Supplier<Boolean> isAttached = () -> false;
private Supplier<Integer> index = () -> null;
private final Function<List<ObserverWrapper<X, Y>>, Boolean> attachFun = observers -> {
isAttached = () -> observers.contains(this);
detach = () -> observers.remove(this);
index = () -> observers.indexOf(this);
return observers.add(this);
};
public boolean attach(List<ObserverWrapper<X, Y>> observers) {
return attachFun.apply(observers);
}
public boolean isAttached() {
return isAttached.get();
}
public Integer observerIndex() {
return index.get();
}
Which some would say is unnecessary in itself, but then it becomes a philosophical problem.
A problem which would not exist if computers didn't exist, and then it becomes a real world problem of indirection.
I may admit that suppliers for me may have become an addiction, but in my mind they feel like the natural extrapolation and extension of all the programming axioms and principles.
You could use a Supplier in a map based factory class
public class StackService {
final static String INTEGERS = "Integers";
final static String DOUBLES = "Doubles";
final static String STRINGS = "Strings";
final static Map<String, Supplier<Stack>> stackType;
static {
stackType = new HashMap<>();
stackType.put(INTEGERS, Stack<Integer>::new);
stackType.put(DOUBLES, Stack<Double>::new);
stackType.put(STRINGS, Stack<String>::new);
}
public Stack<?> createStackOfType(String stackType) {
return stackType.get(stackType).get();
}
}
Here if you were to just use new Stack() you would be returning a reference to the same object rather than a new one.

What is the reason behind "get" method implementation of AtomicMarkableReference in java?

In java an AtomicMarkableReference can be used to update atomically an object reference along with a mark bit.
The javadoc states:
Implementation note: This implementation maintains markable references by creating internal objects representing "boxed" [reference, boolean] pairs.
This is true according to what can be seen in the java 8 source code of the class:
package java.util.concurrent.atomic;
public class AtomicMarkableReference<V> {
private static class Pair<T> {
final T reference;
final boolean mark;
private Pair(T reference, boolean mark) {
this.reference = reference;
this.mark = mark;
}
static <T> Pair<T> of(T reference, boolean mark) {
return new Pair<T>(reference, mark);
}
}
private volatile Pair<V> pair;
public AtomicMarkableReference(V initialRef, boolean initialMark) {
pair = Pair.of(initialRef, initialMark);
}
// [...] class methods
}
Is there a reason behind the design of the get method of the class?
public V get(boolean[] markHolder) {
Pair<V> pair = this.pair;
markHolder[0] = pair.mark;
return pair.reference;
}
What is the point of using such boolean array (instead of returning the pair of values)? Is a concurrency-driven choice? Or perhaps legacy code?
This is because Java has no Pair<L, R> class and probably will not, even despite of the fact that standard library has at least three classes which have private static class Pair. Adding Pair class were discussed by OpenJDK developers more than once and proposal was always rejected. This mail is a very good explanation why pair shouldn't be presented as standard class (also, the whole mail thread is very useful):
The problem is that classes like Pair simply go that much further to indulge
the desire to never have to create any actual types of our own. When we're
forced to create our own types, we begin to model our data more
appropriately, which I believe leads us to create good abstractions at
broader levels of granularity as well.
As long as AtomicMarkableReference doesn't expose its Pair class and in Java you can't change value of passed reference (in the way that such change will be observable by caller), the only way to return both reference and bit flag is to return one of them from method and set second into passed as argument array. So it's not about concurrency, neither about legacy, it's about language design decision.

How to use variables in Java? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 9 years ago.
Improve this question
This question may seem dumb at first, but after having worked with different person, I see everyone seems to have their own, different knowledge about it, so here's my question.
So now I'm wondering what is the best way to do it, and why ("why" is more important for me):
I'm wondering about two methods to write Java code:
Do you always pass Object or can you pass primitive data type ?
Do you call variables using this.name, name or getName() inside your class instance ?
public class MyClass {
private String someStr;
private int someNumber;
private Integer someOtherNumber; // int, Integer ? which one to choose ?
public MyClass(String someStr, int someNumber, int someOtherNumber) { // int someNumber ? Integer someNumber ? why ?
this.someStr = someStr; // Here, it's clearly this.{name} = {name} because of the variable name conflict
this.someNumber = someNumber;
this.someOtherNumber = someOtherNumber;
}
public int someMethod(boolean first) { // Boolean ? boolean ?
if (first) {
return someNumber;
} else {
return this.someOtherNumber; // this.{name} ? just {name} or even this.get{name}() or get{name}() ? (supposing getters exists)
}
}
}
I hope someone will provide me with a great explanation about which to use in order for me to write better code.
Do you always pass Object or can you pass primitive data type ?
You can't pass an Object, only a reference to an Object. You can pass primitive data.
Do you call variables using this.name, name or getName() inside your class instance ?
I don't make it more complicated than I need to, unless it's conflicts with a local variable or my getName() does something special, but that is a matter of style.
Do you always pass Object or can you pass primitive data type ?
You can pass primitives or references to objects depending on your need.
Do you call variables using this.name, name or getName() inside your
class instance ?
this is used to refer to the current object. If there are conflicting variable names and you want to distinguish between the object variable and local variable then use this.
Also you seems to be confused about primitives and Wrapper classes. Wrapper classes provides utilities methods and are of use especially working with collections.
If you need to work with the primitive data types then you should use them, e.g., int, double, char, float, etc. The only exception is String which in Java is a special class that represents a char array and also holds instance methods.
The case with Integer vs int, is when you need to use Integer methods (http://docs.oracle.com/javase/1.5.0/docs/api/java/lang/Integer.html). But if you only need a data type to hold your value then choose int.
Do you always pass Object or can you pass primitive data type ?
public int someMethod(boolean first) { // Boolean ? boolean ?
}
In the following example, you can pass boolean and Boolean with the same success. In Java this is called Autoboxing.
N.B. Be careful, because when passing an object it may be null!
Do you call variables using this.name, name or getName() inside your
class instance ?
Depends. If name is an class member variable, you can access it with name if there isn't any other variable in the current scope that has the same name. In this case you should use this.name to point exactly to the class member variable. getName() may be used, as well. It's just a matter of style.
I keep it simple. I'm using name, but if I have a local variable with the same name I must use this.name (my prefered solution) over getName().
getName() must be used if it do some logic like validation.
Do you always pass Object or can you pass primitive data type ?
It depends on your application and your needs. If you pass a reference to an object, you are able to use the methods of the related type which may be more secure and portable. Let say you are using the class Double. Double has many peer-reviewed and tested methods which may be helpful to you.If you prefer to use primitive type, double, you need to be careful in your manipulations like comparing, validating etc.
For performance issue, you may check a previous discussion below:
Why do people still use primitive types in Java?
Do you call variables using this.name, name or getName() inside your class instance ?
I prefer using this when I refer a class member because i think it will be helpful for others reading my code to understand that the variable is a class member.
Finally, whatever style you prefer, I think you should stick to it in your applications.
Do you call variables using this.name, name or getName() inside your class instance ?
It is mostly a matter of personal style and principle.
private int someOtherNumber; I almost always use int because it seems more natural to me --perhaps influenced by the C days. And, from performance and memory usage point of view using int is a better choice. As a rule of thumb, I don't use objects for primitives unless I have a good reason to.
return this.getSomeOtherNumber(); I prefer using getters/setters; since sometimes -not always- the getter method is not just a simple return statement, rather it encapsulates some logic. As a result, I don't directly access class attributes (like this.someAttr or someClass.somePublicAttr) unless it's a final attribute. Believe me, it's much safer.
Continuing 2: It may seem a bit strange but I, having a strong Lisp background, try to avoid using even getter/setter methods (class state) as much as possible and instead explicity pass the required parameters and use the methods' return values. Consider the following example:
public class C {
private int a;
private int b;
public int getA() { return a; }
public void setA(int a) { this.a = a; }
public int getB() { return a; }
public void setB(int b) { this.b = b; }
// Usual style
public void someMethod1(int x) {
mainLogic1(x);
}
private void mainLogic1(int x) {
b = a + x;
}
// My preferred style
public void someMethod2(int x) {
setB(mainLogic2(x, getA()));
}
private int mainLogic2(int x, int a) {
return x + a;
}
}
As you can see, someMethod1 and mainLogic1 both have side effects which are hard to detect when looking at the code. On the other hand mainLogic2 doesn't have a side effect at all and someMethod2 side effect is easier to spot by just looking. This may seem like overkill, but it has made my Java code more readable, more testable and easier to refactor as it consists of large number of small methods with no side effects.

Is it bad practice to make a setter return "this"?

Is it a good or bad idea to make setters in java return "this"?
public Employee setName(String name){
this.name = name;
return this;
}
This pattern can be useful because then you can chain setters like this:
list.add(new Employee().setName("Jack Sparrow").setId(1).setFoo("bacon!"));
instead of this:
Employee e = new Employee();
e.setName("Jack Sparrow");
...and so on...
list.add(e);
...but it sort of goes against standard convention. I suppose it might be worthwhile just because it can make that setter do something else useful. I've seen this pattern used some places (e.g. JMock, JPA), but it seems uncommon, and only generally used for very well defined APIs where this pattern is used everywhere.
Update:
What I've described is obviously valid, but what I am really looking for is some thoughts on whether this is generally acceptable, and if there are any pitfalls or related best practices. I know about the Builder pattern but it is a little more involved then what I am describing - as Josh Bloch describes it there is an associated static Builder class for object creation.
It's not bad practice. It's an increasingly common practice. Most languages don't require you to deal with the returned object if you don't want to so it doesn't change "normal" setter usage syntax but allows you to chain setters together.
This is commonly called a builder pattern or a fluent interface.
It's also common in the Java API:
String s = new StringBuilder().append("testing ").append(1)
.append(" 2 ").append(3).toString();
To summarize:
it's called a "fluent interface", or "method chaining".
this is not "standard" Java, although you do see it more an more these days (works great in jQuery)
it violates the JavaBean spec, so it will break with various tools and libraries, especially JSP builders and Spring.
it may prevent some optimizations that the JVM would normally do
some people think it cleans code up, others think it's "ghastly"
A couple other points not mentioned:
This violates the principal that each function should do one (and only one) thing. You may or may not believe in this, but in Java I believe it works well.
IDEs aren't going to generate these for you (by default).
I finally, here's a real-world data point. I have had problems using a library built like this. Hibernate's query builder is an example of this in an existing library. Since Query's set* methods are returning queries, it's impossible to tell just by looking at the signature how to use it. For example:
Query setWhatever(String what);
It introduces an ambiguity: does the method modify the current object (your pattern) or, perhaps Query is really immutable (a very popular and valuable pattern), and the method is returning a new one. It just makes the library harder to use, and many programmers don't exploit this feature. If setters were setters, it would be clearer how to use it.
I prefer using 'with' methods for this:
public String getFoo() { return foo; }
public void setFoo(String foo) { this.foo = foo; }
public Employee withFoo(String foo) {
setFoo(foo);
return this;
}
Thus:
list.add(new Employee().withName("Jack Sparrow")
.withId(1)
.withFoo("bacon!"));
Warning: this withX syntax is commonly used to provide "setters" for immutable objects, so callers of these methods might reasonably expect them to create new objects rather than to mutate the existing instance. Maybe a more reasonable wording would be something like:
list.add(new Employee().chainsetName("Jack Sparrow")
.chainsetId(1)
.chainsetFoo("bacon!"));
With the chainsetXyz() naming convention virtually everyone should be happy.
I don't think there's anything specifically wrong with it, it's just a matter of style. It's useful when:
You need to set many fields at once (including at construction)
you know which fields you need to set at the time you're writing the code, and
there are many different combinations for which fields you want to set.
Alternatives to this method might be:
One mega constructor (downside: you might pass lots of nulls or default values, and it gets hard to know which value corresponds to what)
Several overloaded constructors (downside: gets unwieldy once you have more than a few)
Factory/static methods (downside: same as overloaded constructors - gets unwieldy once there is more than a few)
If you're only going to set a few properties at a time I'd say it's not worth returning 'this'. It certainly falls down if you later decide to return something else, like a status/success indicator/message.
If you don't want to return 'this' from the setter but don't want to use the second option you can use the following syntax to set properties:
list.add(new Employee()
{{
setName("Jack Sparrow");
setId(1);
setFoo("bacon!");
}});
As an aside I think its slightly cleaner in C#:
list.Add(new Employee() {
Name = "Jack Sparrow",
Id = 1,
Foo = "bacon!"
});
It not only breaks the convention of getters/setters, it also breaks the Java 8 method reference framework. MyClass::setMyValue is a BiConsumer<MyClass,MyValue>, and myInstance::setMyValue is a Consumer<MyValue>. If you have your setter return this, then it's no longer a valid instance of Consumer<MyValue>, but rather a Function<MyValue,MyClass>, and will cause anything using method references to those setters (assuming they are void methods) to break.
I don't know Java but I've done this in C++.
Other people have said it makes the lines really long and really hard to read,
but I've done it like this lots of times:
list.add(new Employee()
.setName("Jack Sparrow")
.setId(1)
.setFoo("bacon!"));
This is even better:
list.add(
new Employee("Jack Sparrow")
.Id(1)
.foo("bacon!"));
at least, I think. But you're welcome to downvote me and call me an awful programmer if you wish. And I don't know if you're allowed to even do this in Java.
At least in theory, it can damage the optimization mechanisms of the JVM by setting false dependencies between calls.
It is supposed to be syntactic sugar, but in fact can create side effects in the super-intelligent Java 43's virtual machine.
That's why I vote no, don't use it.
It's not a bad practice at all. But it's not compatiable with JavaBeans Spec.
And there is a lot of specification depends on those standard accessors.
You can always make them co-exist to each other.
public class Some {
public String getValue() { // JavaBeans
return value;
}
public void setValue(final String value) { // JavaBeans
this.value = value;
}
public String value() { // simple
return getValue();
}
public Some value(final String value) { // fluent/chaining
setValue(value);
return this;
}
private String value;
}
Now we can use them together.
new Some().value("some").getValue();
Here comes another version for immutable object.
public class Some {
public static class Builder {
public Some build() { return new Some(value); }
public Builder value(final String value) {
this.value = value;
return this;
}
private String value;
}
private Some(final String value) {
super();
this.value = value;
}
public String getValue() { return value; }
public String value() { return getValue();}
private final String value;
}
Now we can do this.
new Some.Builder().value("value").build().getValue();
Because it doesn't return void, it's no longer a valid JavaBean property setter. That might matter if you're one of the seven people in the world using visual "Bean Builder" tools, or one of the 17 using JSP-bean-setProperty elements.
This scheme (pun intended), called a 'fluent interface', is becoming quite popular now. It's acceptable, but it's not really my cup of tea.
If you use the same convention in whole applicaiton it seems fine.
On the oher hand if existing part of your application uses standard convention I'd stick to it and add builders to more complicated classes
public class NutritionalFacts {
private final int sodium;
private final int fat;
private final int carbo;
public int getSodium(){
return sodium;
}
public int getfat(){
return fat;
}
public int getCarbo(){
return carbo;
}
public static class Builder {
private int sodium;
private int fat;
private int carbo;
public Builder sodium(int s) {
this.sodium = s;
return this;
}
public Builder fat(int f) {
this.fat = f;
return this;
}
public Builder carbo(int c) {
this.carbo = c;
return this;
}
public NutritionalFacts build() {
return new NutritionalFacts(this);
}
}
private NutritionalFacts(Builder b) {
this.sodium = b.sodium;
this.fat = b.fat;
this.carbo = b.carbo;
}
}
Paulo Abrantes offers another way to make JavaBean setters fluent: define an inner builder class for each JavaBean. If you're using tools that get flummoxed by setters that return values, Paulo's pattern could help.
I'm in favor of setters having "this" returns. I don't care if it's not beans compliant. To me, if it's okay to have the "=" expression/statement, then setters that return values is fine.
I used to prefer this approach but I have decided against it.
Reasons:
Readability. It makes the code more readable to have each setFoo() on a separate line. You usually read the code many, many more times than the single time you write it.
Side effect: setFoo() should only set field foo, nothing else. Returning this is an extra "WHAT was that".
The Builder pattern I saw do not use the setFoo(foo).setBar(bar) convention but more foo(foo).bar(bar). Perhaps for exactly those reasons.
It is, as always a matter of taste. I just like the "least surprises" approach.
Yes, I think it's a good Idea.
If I could add something, what about this problem :
class People
{
private String name;
public People setName(String name)
{
this.name = name;
return this;
}
}
class Friend extends People
{
private String nickName;
public Friend setNickName(String nickName)
{
this.nickName = nickName;
return this;
}
}
This will work :
new Friend().setNickName("Bart").setName("Barthelemy");
This will not be accepted by Eclipse ! :
new Friend().setName("Barthelemy").setNickName("Bart");
This is because setName() returns a People and not a Friend, and there is no PeoplesetNickName.
How could we write setters to return SELF class instead of the name of the class ?
Something like this would be fine (if the SELF keyword would exist). Does this exist anyway ?
class People
{
private String name;
public SELF setName(String name)
{
this.name = name;
return this;
}
}
This particular pattern is called Method Chaining. Wikipedia link, this has more explanation and examples of how it's done in various programming languages.
P.S: Just thought of leaving it here, since I was looking for the specific name.
On first sight: "Ghastly!".
On further thought
list.add(new Employee().setName("Jack Sparrow").setId(1).setFoo("bacon!"));
is actually less error prone than
Employee anEmployee = new Employee();
anEmployee.setName("xxx");
...
list.add(anEmployee);
So quite interesting. Adding idea to toolbag ...
In general it’s a good practice, but you may need for set-type functions use Boolean type to determine if operation was completed successfully or not, that is one way too. In general, there is no dogma to say that this is good or bed, it comes from the situation, of course.
From the statement
list.add(new Employee().setName("Jack Sparrow").setId(1).setFoo("bacon!"));
i am seeing two things
1) Meaningless statement.
2) Lack of readability.
This may be less readable
list.add(new Employee().setName("Jack Sparrow").setId(1).setFoo("bacon!"));
or this
list.add(new Employee()
.setName("Jack Sparrow")
.setId(1)
.setFoo("bacon!"));
This is way more readable than:
Employee employee = new Employee();
employee.setName("Jack Sparrow")
employee.setId(1)
employee.setFoo("bacon!"));
list.add(employee);
I have been making my setters for quite a while and the only real issue is with libraries that stick with the strict getPropertyDescriptors to get the bean reader/writer bean accessors. In those cases, your java "bean" will not have the writters that you would expect.
For example, I have not tested it for sure, but I would not be surprised that Jackson won't recognizes those as setters when creating you java objects from json/maps. I hope I am wrong on this one (I will test it soon).
In fact, I am developing a lightweight SQL centric ORM and I have to add some code beyong getPropertyDescriptors to recognized setters that returns this.
Long ago answer, but my two cents ... Its fine. I wish this fluent interface were used more often.
Repeating the 'factory' variable does not add more info below:
ProxyFactory factory = new ProxyFactory();
factory.setSuperclass(Foo.class);
factory.setFilter(new MethodFilter() { ...
This is cleaner, imho:
ProxyFactory factory = new ProxyFactory()
.setSuperclass(Properties.class);
.setFilter(new MethodFilter() { ...
Of course, as one of the answers already mentioned, the Java API would have to be tweaked to do this correctly for some situations, like inheritance and tools.
It is better to use other language constructs if available. For example, in Kotlin, you would use with, apply, or let. If using this approach, you won't really need to return an instance from your setter.
This approach allows your client code to be:
Indifferent to the return type
Easier to maintain
Avoid compiler side effects
Here are some examples.
val employee = Employee().apply {
name = "Jack Sparrow"
id = 1
foo = "bacon"
}
val employee = Employee()
with(employee) {
name = "Jack Sparrow"
id = 1
foo = "bacon"
}
val employee = Employee()
employee.let {
it.name = "Jack Sparrow"
it.id = 1
it.foo = "bacon"
}
If I'm writing an API, I use "return this" to set values that will only be set once. If I have any other values that the user should be able to change, I use a standard void setter instead.
However, it's really a matter of preference and chaining setters does look quite cool, in my opinion.
I agree with all posters claiming this breaks the JavaBeans spec. There are reasons to preserve that, but I also feel that the use of this Builder Pattern (that was alluded to) has its place; as long as it is not used everywhere, it should be acceptable. "It's Place", to me, is where the end point is a call to a "build()" method.
There are other ways of setting all these things of course, but the advantage here is that it avoids 1) many-parameter public constructors and 2) partially-specified objects. Here, you have the builder collect what's needed and then call its "build()" at the end, which can then ensure that a partially-specified object is not constructed, since that operation can be given less-than-public visibility. The alternative would be "parameter objects", but that IMHO just pushes the problem back one level.
I dislike many-parameter constructors because they make it more likely that a lot of same-type arguments are passed in, which can make it easier to pass the wrong arguments to parameters. I dislike using lots of setters because the object could be used before it is fully configured. Further, the notion of having default values based on previous choices is better served with a "build()" method.
In short, I think it is a good practice, if used properly.
Bad habit:
a setter set
a getter get
what about explicitly declaring a method, that does it for U
setPropertyFromParams(array $hashParamList) { ... }

Categories