Related
I'm working on a JSONObject with multiple sub-JSONObjects.
Here is the way I fill the content :
myJson.getJSONObject(CAT_NAME).put(VAR_NAME, var)
.put(VAR_NAME2, var2)
.put(...);
A friend told me that it is a very bad practice to use "nested function/method calls" and that I should do it this way :
myJson.getJSONObject(CAT_NAME).put(VAR_NAME, var);
myJson.getJSONObject(CAT_NAME).put(VAR_NAME2, var2);
myJson.getJSONObject(CAT_NAME).put(...);
From my view, my way is more like an chained method call than a nested one.
And I don't like the second way because it force the program to get the same object again and again when the put() method already returns it.
Is my case is a "nested function calls" case ?
Is this dangerous or bad for any reason ? And what are those reasons ?
edit : I don't feel like my question is duplicated. The other question involves chained methods but it mainly talks about c# interfaces.
Is my case is a "nested function calls" case ?
No that is method chaining (Builder pattern).
Is this dangerous or bad for any reason ?
No. Your friend is wrong. Not at all bad practice in your case. It's quite Ok since you are building a Json.
Using method chaining will actually be more efficient than the alternative you provided because myJson.getJSONObject(..) is only called once in the first case, whereas you call it many times in the second. There is a much more significant cost for calling getJSONObject(..) than there is for reusing the original object returned by it.
The correct way to accomplish this without using method chaining would be more like this:
JSONObject obj = myJson.getJSONObject(CAT_NAME);
obj.put(VAR_NAME, var);
obj.put(VAR_NAME2, var2);
obj.put(...);
Personally, I prefer to not use method chaining because I think it looks better, but ultimately it's your preference and the code here would have basically the same performance as your first chunk of code.
He PROBABLY considers it bad because it can be less readable (but that's a personal opinion and depends a lot on code formating, how well someone understands the specific APIs, is familiar with the concept of method chaining, etc. etc.).
It's certainly not a generally bad thing to do though. In fact a lot of APIs work exactly like that. Just look at StringBuilder in the Java standard API as a very commonly used example.
As others already pointed out it's potentially more performant (depending on how the called methods are implemented) as well, but that's not a given.
Optional type introduced in Java 8 is a new thing for many developers.
Is a getter method returning Optional<Foo> type in place of the classic Foo a good practice? Assume that the value can be null.
Of course, people will do what they want. But we did have a clear intention when adding this feature, and it was not to be a general purpose Maybe type, as much as many people would have liked us to do so. Our intention was to provide a limited mechanism for library method return types where there needed to be a clear way to represent "no result", and using null for such was overwhelmingly likely to cause errors.
For example, you probably should never use it for something that returns an array of results, or a list of results; instead return an empty array or list. You should almost never use it as a field of something or a method parameter.
I think routinely using it as a return value for getters would definitely be over-use.
There's nothing wrong with Optional that it should be avoided, it's just not what many people wish it were, and accordingly we were fairly concerned about the risk of zealous over-use.
(Public service announcement: NEVER call Optional.get unless you can prove it will never be null; instead use one of the safe methods like orElse or ifPresent. In retrospect, we should have called get something like getOrElseThrowNoSuchElementException or something that made it far clearer that this was a highly dangerous method that undermined the whole purpose of Optional in the first place. Lesson learned. (UPDATE: Java 10 has Optional.orElseThrow(), which is semantically equivalent to get(), but whose name is more appropriate.))
After doing a bit of research of my own, I've come across a number of things that might suggest when this is appropriate. The most authoritative being the following quote from an Oracle article:
"It is important to note that the intention of the Optional class is not to replace every single null reference. Instead, its purpose is to help design more-comprehensible APIs so that by just reading the signature of a method, you can tell whether you can expect an optional value. This forces you to actively unwrap an Optional to deal with the absence of a value." - Tired of Null Pointer Exceptions? Consider Using Java SE 8's Optional!
I also found this excerpt from Java 8 Optional: How to use it
"Optional is not meant to be used in these contexts, as it won't buy us anything:
in the domain model layer (not serializable)
in DTOs (same reason)
in input parameters of methods
in constructor parameters"
Which also seems to raise some valid points.
I wasn't able to find any negative connotations or red flags to suggest that Optional should be avoided. I think the general idea is, if it's helpful or improves the usability of your API, use it.
I'd say in general its a good idea to use the optional type for return values that can be nullable. However, w.r.t. to frameworks I assume that replacing classical getters with optional types will cause a lot of trouble when working with frameworks (e.g., Hibernate) that rely on coding conventions for getters and setters.
The reason Optional was added to Java is because this:
return Arrays.asList(enclosingInfo.getEnclosingClass().getDeclaredMethods())
.stream()
.filter(m -> Objects.equals(m.getName(), enclosingInfo.getName())
.filter(m -> Arrays.equals(m.getParameterTypes(), parameterClasses))
.filter(m -> Objects.equals(m.getReturnType(), returnType))
.findFirst()
.getOrThrow(() -> new InternalError(...));
is cleaner than this:
Method matching =
Arrays.asList(enclosingInfo.getEnclosingClass().getDeclaredMethods())
.stream()
.filter(m -> Objects.equals(m.getName(), enclosingInfo.getName())
.filter(m -> Arrays.equals(m.getParameterTypes(), parameterClasses))
.filter(m -> Objects.equals(m.getReturnType(), returnType))
.getFirst();
if (matching == null)
throw new InternalError("Enclosing method not found");
return matching;
My point is that Optional was written to support functional programming, which was added to Java at the same time. (The example comes courtesy of a blog by Brian Goetz. A better example might use the orElse() method, since this code will throw an exception anyway, but you get the picture.)
But now, people are using Optional for a very different reason. They're using it to address a flaw in the language design. The flaw is this: There's no way to specify which of an API's parameters and return values are allowed to be null. It may be mentioned in the javadocs, but most developers don't even write javadocs for their code, and not many will check the javadocs as they write. So this leads to a lot of code that always checks for null values before using them, even though they often can't possibly be null because they were already validated repeatedly nine or ten times up the call stack.
I think there was a real thirst to solve this flaw, because so many people who saw the new Optional class assumed its purpose was to add clarity to APIs. Which is why people ask questions like "should getters return Optionals?" No, they probably shouldn't, unless you expect the getter to be used in functional programming, which is very unlikely. In fact, if you look at where Optional is used in the Java API, it's mainly in the Stream classes, which are the core of functional programming. (I haven't checked very thoroughly, but the Stream classes might be the only place they're used.)
If you do plan to use a getter in a bit of functional code, it might be a good idea to have a standard getter and a second one that returns Optional.
Oh, and if you need your class to be serializable, you should absolutely not use Optional.
Optionals are a very bad solution to the API flaw because a) they're very verbose, and b) They were never intended to solve that problem in the first place.
A much better solution to the API flaw is the Nullness Checker. This is an annotation processor that lets you specify which parameters and return values are allowed to be null by annotating them with #Nullable. This way, the compiler can scan the code and figure out if a value that can actually be null is being passed to a value where null is not allowed. By default, it assumes nothing is allowed to be null unless it's annotated so. This way, you don't have to worry about null values. Passing a null value to a parameter will result in a compiler error. Testing an object for null that can't be null produces a compiler warning. The effect of this is to change NullPointerException from a runtime error to a compile-time error.
This changes everything.
As for your getters, don't use Optional. And try to design your classes so none of the members can possibly be null. And maybe try adding the Nullness Checker to your project and declaring your getters and setter parameters #Nullable if they need it. I've only done this with new projects. It probably produces a lot of warnings in existing projects written with lots of superfluous tests for null, so it might be tough to retrofit. But it will also catch a lot of bugs. I love it. My code is much cleaner and more reliable because of it.
(There is also a new language that addresses this. Kotlin, which compiles to Java byte code, allows you to specify if an object may be null when you declare it. It's a cleaner approach.)
Addendum to Original Post (version 2)
After giving it a lot of thought, I have reluctantly come to the conclusion that it's acceptable to return Optional on one condition: That the value retrieved might actually be null. I have seen a lot of code where people routinely return Optional from getters that can't possibly return null. I see this as a very bad coding practice that only adds complexity to the code, which makes bugs more likely. But when the returned value might actually be null, go ahead and wrap it inside an Optional.
Keep in mind that methods that are designed for functional programming, and that require a function reference, will (and should) be written in two forms, one of which uses Optional. For example, Optional.map() and Optional.flatMap() both take function references. The first takes a reference to an ordinary getter, and the second takes one that returns Optional. So you're not doing anyone a favor by return an Optional where the value can't be null.
Having said all that, I still see the approach used by the Nullness Checker is the best way to deal with nulls, since they turn NullPointerExceptions from runtime bugs to compile time errors.
If you are using modern serializers and other frameworks that understand Optional then I have found these guidelines work well when writing Entity beans and domain layers:
If the serialization layer (usually a DB) allows a null value for a cell in column BAR in table FOO, then the getter Foo.getBar() can return Optional indicating to the developer that this value may reasonably be expected to be null and they should handle this. If the DB guarantees the value will not be null then the getter should not wrap this in an Optional.
Foo.bar should be private and not be Optional. There's really no reason for it to be Optional if it is private.
The setter Foo.setBar(String bar) should take the type of bar and not Optional. If it's OK to use a null argument then state this in the JavaDoc comment. If it's not OK to use null an IllegalArgumentException or some appropriate business logic is, IMHO, more appropriate.
Constructors don't need Optional arguments (for reasons similar to point 3). Generally I only include arguments in the constructor that must be non-null in the serialization database.
To make the above more efficient, you might want to edit your IDE templates for generating getters and corresponding templates for toString(), equals(Obj o) etc. or use fields directly for those (most IDE generators already deal with nulls).
You have to keep in mind that the often-cited advice came from people who had little experience outside Java, with option types, or with functional programming.
So take it with a grain of salt. Instead, let's look at it from the "good practice" perspective:
Good practice not only means asking "how do we write new code?", but also "what happens to existing code?".
In the case of Optional, my environment found a good and easy to follow answer:
Optional is mandatory to indicate optional values in records:
record Pet(String name, Optional<Breed> breed,
Optional<ZonedDateTime> dateOfBirth)
This means that existing code is good as-is, but code that makes use of record (that is, "new code") causes widespread adoption of Optional around it.
The result has been a complete success in terms of readability and reliability. Just stop using null.
At the company I work for there's a document describing good practices that we should adhere to in Java. One of them is to avoid methods that return this, like for example in:
class Properties {
public Properties add(String k, String v) {
//store (k,v) somewhere
return this;
}
}
I would have such a class so that I'm able to write:
properties.add("name", "john").add("role","swd"). ...
I've seen such idiom many times, like in StringBuilder and don't find anything wrong with it.
Their argumentation is :
... can be the source of synchronization problems or failed expectations about the states of target objects.
I can't think of a situation where this could be true, can any of you give me an example?
EDIT The document doesn't specify anything about mutability, so I don't see the diference between chaining the calls and doing:
properties.add("name", "john");
properties.add("role", "swd");
I'll try to get in touch with the originators, but I wanted to do it with my guns loaded, thats' why I posted the question.
SOLVED: I got to talk with one of the authors, his original intention was apparently to avoid releasing objects that are not yet ready, like in a Builder pattern, and explained that if a context switch happens between calls, the object could be in an invalid state. I argued that this had nothing to do with returning this since you could make the same mistake buy calling the methods one by one and had more to do with synchronizing the building process properly. He admitted the document could be more explicit and will revise it soon. Victory is mine/ours!
My guess is that they are against mutable state (and often are rightly so). If you are not designing fluent interfaces returning this but rather return a new immutable instance of the object with the changed state, you can avoid synchronization problems or have no "failed expectations about the states of target objects". This might explain their requirement.
The only serious basis for the practice is avoiding mutable objects; the criticism that it is "confusing" and leads to "failed expectations" is quite weak. One should never use an object without first getting familiar with its semantics, and enforcing constraints on the API just to cater for those who opt out of reading Javadoc is not a good practice at all— especially because, as you note, returning this to achieve a fluent API design is one of the standard approaches in Java, and indeed a very welcome one.
I think sometimes this approach can be really useful, for example in 'builder' pattern.
I can say that in my organization this kind of things is controlled by Sonar rules, and we don't have such a rule.
Another guess is that maybe the project was built on top of existing codebase and this is kind of legacy restriction.
So the only thing I can suggest here is to talk to the people who wrote this doc :)
Hope this helps
I think it's perfectly acceptable to use that pattern in some situations.
For example, as a Swing developer, I use GridBagLayout fairly frequently for its strengths and flexibility, but anyone who's ever used it (with it's partener in crime GridBagConstraints) knows that it can be quite verbose and not very readable.
A common workaround that I've seen online (and one that I use) is to subclass GridBagConstraints (GBConstraints) that has a setter for each different property, and each setter returns this. This allows for the developer to chain the different properties on an as-needed basis.
The resultant code is about 1/4 the size, and far more readable/maintainable, even to the casual developer who might not be familiar with using GridBagConstaints.
I have a class named ActivityLog. This class holds a list of ActivityRecords. I want to return a list of ActivityRecords by these criterias: Environment and Condition. Should the method name include the "criteria"? See example:
activityLog.allRecords();
activityLog.allRecordsBy(Environment environment);
activityLog.allRecordsBy(Condition condition);
activityLog.allRecordsBy(Condition condition, Environment environment);
or
activityLog.allRecordsByEnvironment(Environment environment);
activityLog.allRecordsByCondtion(Condition condition);
I probably think the first is better because you will read the method name and you will understand from the parameter what it does, but I may be wrong? Which is the best, or are there even better alternatives?
I could have named the methods records(), recordsBy etc. too, but I want to have a consitency through my API where you always start writing all for lists of objects so you get help from for example Intelli Sense.
I like putting the criteria in the actual method name. So I would use:
activityLog.allRecordsByEnvironment(Environment environment);
To me proper method naming expresses a small summary of what the method does. Since the parameters are included in the method signature I would not consider the parameters to be part of the actual name, therefore not placing the criteria in the name gives the user of an api incomplete information about the methods functionality. (IMO)
I applaud your effort to practice self documenting code, great practice.
I like the overloaded variant (your first example), because it communicates that the methods are all related and provide largely the same functionality, aka, you are returning records, filtered by some criteria. You will see examples of this in many open source libraries and even the SDK itself.
I'd treat it the same as static factory methods, which are named constructors. And there not only parameter says what this method does, its name itself does it. So I'd choose 2nd option.
#Bob, about names being too long - even if you would put 2 parameters into its name, it still would be ok for me. Anyway you should avoid having methods with more than 3 parameters. Following this rule will prevent your methods' names from being enormous long.
I would take the first one.
If these methods are doing the same thing or providing the same functionality then they should have the same name. But be aware of Effective Java Item 41 and 42. You've to ensure that at least one corresponding param of overloaded method are having radically different types.
The 2nd approach becomes ugly very fast with every param added. I see this in often in Broker classes at work. There are people writing methods like findByFirstnameAndLastnameAndBirthdayOrderByUgliness(blablub). No comment.
Methods in OOP represent behavior, so I would name all of them getRecords() and made them overloaded.
In my opinion, specifying criteria in the name of method looks like naming heirarchy classes like this
Car -> BMW_Car -> X5_BMW_Car
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 4 years ago.
Improve this question
Should I be writing Doc Comments for all of my java methods?
#Claudiu
When I write code that others will use - Yes. Every method that somebody else can use (any public method) should have a javadoc at least stating its obvious purpose.
#Daniel Spiewak
I thoroughly document every public method in every API class. Classes which have public members but which are not intended for external consumption are prominently marked in the class javadoc. I also document every protected method in every API class, though to a lesser extent. This goes on the idea that any developer who is extending an API class will already have a fair concept of what's going on.
Finally, I will occasionally document private and package private methods for my own benefit. Any method or field that I think needs some explanation in its usage will receive documentation, regardless of its visibility.
#Paul de Vrieze
For things, like trivial getters and setters, share the comment between then and describe the purpose of the property, not of the getter/setter
/**
* Get the current value of the foo property.
* The foo property controls the initial guess used by the bla algorithm in
* {#link #bla}
* #return The initial guess used by {#link #bla}
*/
int getFoo() {
return foo;
}
And yes, this is more work.
#VonC
When you break a huge complex method (because of high cyclomatic complexity reason) into:
one public method calling
several private methods which represent internal steps of the public one
, it is very useful to javadoc the private methods as well, even though that documentation will not be visible in the javadoc API files.
Still, it allows you to remember more easily the precise nature of the different steps of your complex algorithm.
And remember: limit values or boundary conditions should be part of your javadoc as well.
Plus, javadoc is way better than simple "//comment":
It is recognized by IDE and used to display a pop-up when you move your cursor on top of one of your - javadoc-ed - function. For instance, a constant - that is private static final variable -, should have a javadoc, especially when its value is not trivial. Case in point: regexp (its javadoc should includes the regexp in its non-escaped form, what is purpose is and a literal example matched by the regexp)
It can be parsed by external tools (like xdoclet)
#Domci
For me, if somebody will see it or not doesn't matter - it's not likely I'll know what some obscure piece of code I wrote does after a couple of months. [...]
In short, comment logic, not syntax, and do it only once, on a proper place.
#Miguel Ping
In order to comment something, you have to understand it first. When you trying to comment a function, you are actually thinking of what the method/function/class does, and this makes you be more specific and clear in your javadoc, which in turn makes you write more clear and concise code, which is good.
If the method is, obviously self evident, I might skip a javadoc comment.
Comments like
/** Does Foo */
void doFoo();
Really aren't that useful. (Overly simplistic example, but you get the idea)
I thoroughly document every public method in every API class. Classes which have public members but which are not intended for external consumption are prominently marked in the class javadoc. I also document every protected method in every API class, though to a lesser extent. This goes on the idea that any developer who is extending an API class will already have a fair concept of what's going on.
Finally, I will occasionally document private and package private methods for my own benefit. Any method or field that I think needs some explanation in its usage will receive documentation, regardless of its visibility.
All bases covered by others already; one additional note:
If you find yourself doing this:
/**
* This method currently launches the blaardh into the bleeyrg.
*/
void execute() { ... }
Consider changing it into this:
void launchBlaardhIntoBleeyrg() { ... }
This may seem a bit obvious, but in many cases the opportunity is easy to miss in your own code.
Finally keep in mind that the change is not always wanted; for instance the behaviour of the method may be expected to evolve over time (note the word "currently" in the JavaDoc).
For things, like trivial getters and setters, share the comment between then and describe the purpose of the property, not of the getter/setter.
/**
* Get foo
* #return The value of the foo property
*/
int getFoo() {
return foo;
}
Is not useful. Better do something like:
/**
* Get the current value of the foo property.
* The foo property controls the initial guess used by the bla algorithm in
* {#link #bla}
* #return The initial guess used by {#link #bla}
*/
int getFoo() {
return foo;
}
And yes, this is more work.
No, do not comment every method, variable, class, etc..
Here's a quote from "Clean Code: A Handbook of Agile Software Craftsmanship":
It is just plain silly to have a rule that says that every function must have a
javadoc, or every variable must have a comment. Comments like this just clutter
up the code, popagate lies, and lend to general confusion and disorganization.
A comment should exist if, and only if, it adds important information for the intended user of the method, variable, class, etc.. What constitutes "important" is worth consideration and could be a reminder to myself when/if I come back to this method/class/etc., a consequence/side effect of the method, motivation for why the thing even exists (in the case where some code is overcoming a shortcoming/bug of some library or system), important information about the performance or when it is appropriate to call, etc..
What is not a good comment but indicates the code itself should be rewritten/modified is a comment explaining the details of a complex and obscure method or function. Instead, prefer shorter clearer code.
When I write code for myself - NO. In this case, java doccing is a waste of my time.
When I write code that others will use - Yes. Every method that somebody else can use (any public method) should have a java doc at least stating its obvious purpose. For a good test - run the javadoc creation utility on your code (I forget the exact command line now). Browse through the webpage it generates. If you would be satisfied using a library with that level of documentation, you're golden. If not, Write more javadocs in your code.
There is another reason you should use javadocs. In order to comment something, you have to understand it first. When you trying to comment a function, you are actually thinking of what the method/function/class does, and this makes you be more specific and clear in your javadoc, which in turn makes you write more clear and concise code, which is good.
simply put: YES
The time you need to think about whether you should write a doc,
is better invested in writing a doc.
Writing a one-liner is better than spending time for not documenting the method at all in the end.
For me, if somebody will see it or not doesn't matter - it's not likely I'll know what some obscure piece of code I wrote does after a couple of months. There are a few guidelines:
APIs, framework classes, and internal reusable static methods should be commented thoroughly.
Logic in every complicated piece of code should be explained on two places - general logic in javadoc, and logic for each meaningful part of code in it's own comment.
Model properties should be commented if they're not obvious. For example, no point in commenting username and password, but type should at least have a comment which says what are possible values for type.
I don't document getters, setters, or anything done "by the book". If the team has a standard way of creating forms, adapters, controllers, facades... I don't document them, since there's no point if all adapters are the same and have a set of standard methods. Anyone familiar with framework will know what they're for - assuming that the framework philosophy and way of working with it is documented somewhere. In this cases, comments mean additional clutter and have no purpose. There are exceptions to this when class does something non-standard - then short comment is useful. Also, even if I'm creating form in a standard way, I like to divide parts of the form with short comments which divide the code into several parts, for example "billing address starts here".
In short, comment logic, not syntax, and do it only once, on a proper place.
Java doc should not be relied on, as it places a burden on developers making changes to maintain the java doc as well as the code.
Class names and function names should be explicit enough to explain what is going on.
If to explain what a class or method does makes its name too long to deal with, the class or method is not focused enough, and should be refactored into smaller units.
I feel there should at least be comments regarding the parameters accepted and return types in term of what they are.
One can skip the implementation details in case the function names describes it completely, for eg, sendEmail(..);
I make it a point to write javadoc comments whenever it is non-trivial, Writing javadoc comments when using an IDE like eclipse or netbeans isn't that troublesome. Besides, when you write a javadoc comment, you are being forced to think about not just what the method does, but what the method does exactly, and the assumptions you've made.
Another reason is that once you've understood your code and refactored it, the javadoc allows you to forget about what it does since you can always refer to it. I'm not advocating purposely forgetting what your methods do but it's just that I prefer to remember other things which are more important.
You should probably be documenting all of your methods really. Most important are public API methods (especially published API methods). Private methods are sometimes not documented, although I think they should be, just for clarity - same goes with protected methods. Your comments should be informative, and not just reiterate what the code does.
If a method is particularly complex, it is advised that you document it. Some people believe that code should be written clearly so that it doesn't require comments. However, this is not always possible, so comments should be used in these cases.
You can automate the generation of Javadoc comments for getters/setters from Eclipse via the code templates to save on the amount of documentation you have to write. another tip is to use the #{$inheritDoc} to prevent duplication of code comments between interfaces and implementation classes.
Javadoc can be really useful for libraries and reusable components. But let's be more practical. It is more important to have self explaining code than javadoc.
If you imagine a huge legacy project with Javadocs - would you rely on that? I do not think so... Someone has added Javadoc, then the implementation has changed, new feature was added (removed), so the Javadoc got obsolete.
As I mentioned I like to have javadocs for libraries, but for active projects I would prefer
small functions/classes with names which describe what they do
clear unit test cases which give explanation what the
function/classes do
at a previous company, we used to use the jalopy code formatter with eclipse. That would add javadoc to all the methods including private.
It made life difficult to document setters and getters. But what the heck. You have to do it -- you do it. That made me learn some macro functionality with XEmacs :-) You can automate it even further by writing a java parser and commenter like ANTLR creator did several years ago :-)
currently, I document all public methods and anything more than 10 lines.
You can run javadoc against code that does not have javadoc comments and it will produce fairly useable javadocs if you give thoughtful names to your methods and parameters.
I try to at the very least document every public and interface property and method, so that people calling into my code know what things are. I also try to comment as much as possible in line as well for maintenance sake. Even 'personal' projects I do on my own time just for myself, I try to javadoc just because I might shelf it for a year and come back to it later.
Assumed in all the answers so far is that the comments will be good comments. As we all know that is not always the case, sometimes they are even incorrect. If you have to read the code to determine its intent, boundaries, and expected error behavior then the comment is lacking. For example, is the method thread safe, can any arg be null, can it return null, etc. Comments should be part of any code reviews.
This may be even more important for private methods since a maintainer of the code base will have to contend with issues that an API user will not.
Perhaps IDEs should have a feature that allows the use of a documenting form so that the developer can check off various properties that are important and applicable for the current method.