• Post Reply Bookmark Topic Watch Topic
  • New Topic

Small private methods vs. Anonymous blocks.  RSS feed

 
Avor Nadal
Ranch Hand
Posts: 156
Java Netbeans IDE Postgres Database
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hello:

Following the tendency of writing self-documenting code, during the last years, I've been dividing my code in many small private methods. I haven't been dividing it according to metrics, but applying a separation of concerns. It looked like a good way to limit the scope of the variables and, at the same time, to avoid writing so many comments. However, I've always had the feeling that self-documenting code is a myth and that comments are still helpful. Not only because the typical argument that they explain the "whys", but also because you can explain other useful information that doesn't fit in a method name.

Some days ago I had to do the maintenance of an old application that I wrote years ago. It was the classic code with comments before each block of code. In this case, by "block" I'm referring to a paragraph of code, not to a block in the sense of something delimited by curly braces. To my surprise, my feeling was that it was easier to understand what I wrote there than what I've written in some of my current projects, composed by lots of small methods.

But there were still a problem with the scope of some variables. It was too broad. I tried to put them in anonymous blocks and it just worked. I thought that the resulting code was going to look like ugly, but it didn't.

So I decided to apply this style to a class that I had written for a modern project, to check what was my impression. When I used the technique of extracting code to small methods I needed to build at least 2 static inner classes, simply to return some composite results. But with the old style, it was easier to read and understand. There were less jumps between methods, less passings of parameters here and there... It was easier to track the execution mentally.

So my question is what you do you opine of all this. Do you think it's OK to use anonymous blocks instead of many small private methods? Of course, this wouldn't imply not to extract some code to methods when appropriate. I still would make private methods for code that could be re-used internally, and I also would make new classes for that code that belongs to a different level of abstraction or functionality (separation of concerns again). Nowadays I don't test private methods, because I've read that it's not a good practice. So I wouldn't lose that possible benefit if I moved their code to anonymous blocks.

Thank you.
 
Stevens Miller
Bartender
Posts: 1445
30
C++ Java Netbeans IDE Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
How about posting a few "before" and "after" cases for us to review?
 
Winston Gutkowski
Bartender
Posts: 10575
66
Eclipse IDE Hibernate Ubuntu
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I agree with Stevens: show us an example or two.

However, in the absence of any, I think my answer would be that there are very few cases - and of the top of my head, I can't think of any - where I would prefer an anonymous block (by which I assume you mean a pair of braces) to a private method. And here's why:

1. If a method already contains so much code that it needs to be "paragraphed", it's probably too big anyway.
2. Methods can be given a name which, if chosen well, often precludes the need for any "why" documentation - or indeed any searching to find out how it's implemented.
3. Method documentation can always be produced by Javadoc - even private stuff - just change the "inclusion level". And that allows you to use links (as long as you're careful).
4. A properly decoupled method can be changed without affecting anything else; and it already gives you the "scope" characteristics you want. I doubt that the same is true of a block; especially in the context you describe.
5. What is the logical difference between an anonymous block, and a named method with no parameters? I can think of only one, and it's actually a major reason why I'd prefer the latter: because a method can return a value.

My 2¢. YMMV.

Winston
 
Les Morgan
Rancher
Posts: 779
19
C++ Java MySQL Database Netbeans IDE Oracle Tomcat Server
  • Likes 2
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Avor,
I think you have answered your own question before you even asked it. You said you think your old style of coding was more understandable.

No where have you said you are coding projects for others to read and maintain, so I'll assume you are coding for yourself. If that is the case you have done your acid test, and that is to come back and look at code you have written in your old style and compare and contrast that to your new style.

I have coded now for a considerable amount of time in many different languages and for several different organizations, and inevitably the simplest and cleanest style is always the one most readable and maintainable. When I code, I have to ask myself: can I expect someone just out of college with no experience be expected to pick this code up and be able to read and understand what it does. Is there anything in the code that may hide the intention or the process that is going on in each and every method. Does each class have a homogeneous reason for existence and operation making it obvious why it's members have been included--in most cases where I want to use an anonymous block I find that there is something wrong in my way of thinking, because the expectation is that the newbie will not understand what is being done and why.

Too many small methods may be more distinct and clear as to what each is doing, but also, if you are 4, 5, or even 6 or more methods deep in a calling structure for a simple act, then the test comes back in: will a newbie be able to follow what is being done--the deeper you get in calling structure, the more apt a person is to lose track of what is happening and why--they just cannot fit it into their head and track that many things at a time.

Now if understandability is not your goal, and you are trying to disguise what is happening--I do not think you are--then obfuscate the daylights out of it, and if only you need to be able to read it, then the answer is: what ever you like best. If, on the other hand, you have a code base that needs to be maintained for others to be able to read, then anything in your style of coding that makes it difficult for a newbie to grasp needs to be rethought.

Les
 
Knute Snortum
Sheriff
Posts: 4279
127
Chrome Eclipse IDE Java Postgres Database VI Editor
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Well said; have a cow.
 
Stevens Miller
Bartender
Posts: 1445
30
C++ Java Netbeans IDE Windows
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Yup, all of the above works for me, too. What you find works best when you look at your own old code, if you are the only person likely ever to see it, is the right choice.

However... when others must cope with your code, I will (after 40 years of writing computer programs) say this: there is no such thing as self-documenting code.

Let me say that again: There is no such thing as self-documenting code.

And, because over half my life has taught me this, one more time: There is NO SUCH THING AS SELF-DOCUMENTING CODE!!!
 
Avor Nadal
Ranch Hand
Posts: 156
Java Netbeans IDE Postgres Database
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
As usually, I'm sorry for the delay in my answer. These have been some busy days. And thank you all for your answers! They've been very helpful.

Because I'm not allowed to publish these parts of the code (I've asked for permission before), I have tried to write some examples. However, they haven't pleased me enough, because they don't come from real-life situations and they look like too artificial. But writing them has been a good exercise. Because, while I was doing it, I've realized that its value had much to do with their POSITION, apart of its content, of course. The fact that they're located right before the variables that form the "product", gives me a clue about what all that variables mean, without needing long names for them. In other words, the comments give the variables a context.

So I've decided to do an experiment and replace the comments with the variable that represents the product or result of each block. I'm sorry for the silly example. Let's suppose that I had this:



I've replaced this with:



And with this:



And I've felt that, putting the name of the result on the top, it was as much clear as with the comment. Before you all shout it to me :P : this piece of code can be extracted to a single method, called "assembleWheel", for example. Indeed that's what I do nowadays when I program. Just as you recommend . But let me explain where my concern came from originally.

It came from the fact that I use LOTS of explaining temporary variables, to make the code easy to understand to everyone. Specially to know what are the arguments passed to each method call, without requiring an IDE. This forces me to create many interdependent private methods and constants, in parts where people usually had written a singe line of calls and have the job done (I've seen this even in some auto-proclaimed self-documenting code :S ). Following some advices, I've started to JavaDoc even the private members. But this is resulting in a madness, with very similar sentences everywhere and lots of repetitions. So when I saw my old code, I felt tempted to remove private methods and use that style to avoid so much repetition. But you were right. It wasn't such a good idea, because I lot other advantages.

Taking into account that I'm not creating APIs but programs, and that I try to use descriptive names internally; if you were a programmer that worked with me, Would you have enough if I simply documented the classes (not its members) and put a brief summary about the implementation in a private comment (under the class declaration, for example)?

Thank you!
 
Stephan van Hulst
Saloon Keeper
Posts: 7986
143
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Again, I think you've answered your own question. If you're repeating in comments what's in (private) code, then why write the comments at all? The point of using the private methods is to make the code more legible. If the comments make the code less readable, then leave them out. I rarely document my private methods because most of them are very short and have descriptive names. At most, I document exotic parameters and what exceptions are thrown. It seems pointless to write comments because of the dogmatic "all members must be documented".

Members used outside of the class should be well documented though, because those are the parts that have to be unit tested.
 
Avor Nadal
Ranch Hand
Posts: 156
Java Netbeans IDE Postgres Database
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Les Morgan wrote:...


Although I develop alone (we're only two people in my company), I like applying rules to my code as if it were going to be read by other people. I guess that it's because of 2 reasons. The first one is that I'm in charge of big applications, so I benefit of the code clarity from time to time (not as much as if I were in a team, I know). And the second one it's that I've always wished to participate in collaborative projects but I've never felt able (lack of time, lack of knowledge).
 
Dave Tolls
Ranch Foreman
Posts: 3061
37
  • Likes 2
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
The drawback of lots of commenting on things like private methods is that, as bugs are fixed and tweaks are made, the code drifts from the comments and they rapidly become detrimental to understanding the code.

Yes, sometimes a brief description is necessary for an algorithm, but 99% of code really shouldn't need it.
 
Avor Nadal
Ranch Hand
Posts: 156
Java Netbeans IDE Postgres Database
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Stephan van Hulst wrote:Again, I think you've answered your own question. If you're repeating in comments what's in (private) code, then why write the comments at all? The point of using the private methods is to make the code more legible. If the comments make the code less readable, then leave them out. I rarely document my private methods because most of them are very short and have descriptive names. At most, I document exotic parameters and what exceptions are thrown. It seems pointless to write comments because of the dogmatic "all members must be documented".

Members used outside of the class should be well documented though, because those are the parts that have to be unit tested.


Right, that's what I believe too; that the descriptions of the private methods (as a fixed rule) are repetitive and useless. So I think that I'll stop following that advice.

But I also feel something similar when I write JavaDocs for many of my public members. For example, many times the JavaDoc at the class level is so clear that the descriptions of the methods become extremely repetitive. At least in the context of a program. If it were an API, it would be different, because people don't want to have to read the internal code to know the conditions, obviously. I believe that there should be better tools to write JavaDocs, at least in the IDEs. Something that allowed to replicate code from a single part in other different parts (using IDs or something).
 
Stephan van Hulst
Saloon Keeper
Posts: 7986
143
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Well, for anything that's not private, you should at least use the @throws and @return tags, if applicable. If the methods are mutators that are more than simple setters, you should also document the post-conditions. This is important for unit-testing all applications, not just APIs.

Remember that your class outline automatically becomes somewhat of an API if you use public and protected access, because even if you don't publish your code, they may still end up in modules that are reused by your company.
 
Avor Nadal
Ranch Hand
Posts: 156
Java Netbeans IDE Postgres Database
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Stephan van Hulst wrote:Well, for anything that's not private, you should at least use the @throws and @return tags, if applicable. If the methods are mutators that are more than simple setters, you should also document the post-conditions. This is important for unit-testing all applications, not just APIs.

Remember that your class outline automatically becomes somewhat of an API if you use public and protected access, because even if you don't publish your code, they may still end up in modules that are reused by your company.


I see. I will try to get used to that. I'll check what kind of aids are provided by NetBeans IDE in that sense. A mechanism to edit the same paragraph in different places would be the most useful. But I already "played" with NetBeans IDE when I wrote some JavaDocs and couldn't find anything like that. So I guess that I will have to build a custom program to do that.

I've another doubt not directly related with this one, by the way. But I'm going to open a new thread, so that I don't mix different topics.

Thank you all for your help!
 
Stephan van Hulst
Saloon Keeper
Posts: 7986
143
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
What do you mean, the same paragraph in different places?
 
Winston Gutkowski
Bartender
Posts: 10575
66
Eclipse IDE Hibernate Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Avor Nadal wrote:Let's suppose that I had this:...

Thanks for the example, but it makes me wonder if you couldn't make the code just as readable with a Builder, viz:Indeed, all those 'create...' methods suggest that you may want to have one for each of your 'component' classes (Rim, Tyre etc) as well ... or maybe just use normal construction - ie:
  new Rim(material, colour)

Now I quite understand that you (or the person whose code you're maintaining) may not be familiar with the Builder pattern, but it seems to me that your example is trying to solve a construction problem - creating an object with many constituent parts - with a coding technique rather than with classes. And that in itself should be a red flag.

It's also where sites like ours can be very useful - If you'd come to us with this problem earlier on in the process, I'm pretty sure that someone here would have suggested something similar; and possibly saved you all that time spent "arranging" your code.

I should add that it's by no means the only solution, but it seems to fit this particular example.

HIH

Winston
 
Avor Nadal
Ranch Hand
Posts: 156
Java Netbeans IDE Postgres Database
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Stephan van Hulst wrote:What do you mean, the same paragraph in different places?


I mean paragraphs that are repeated several times in the JavaDocs of one ore more classes. Although you can use the @see and @link tags to mitigate the repetition up to certain degree, sometimes it's undesirable to use one of that tags.

For example, some times you just want to repeat the same pre-conditions of a specific @param tag in several methods that use it. It's very typical when you overload methods. It would be nice if you could edit it in one place, and that the changes were reflected in the other @param tags too.

But I could go further and make this need extensible to several classes. For example, I've many EJBs which may throw the same type of exception, because of the same reason. This means that the descriptions of their @throw tags are exactly the same. If I want to do a small change, I've to run a search & replace to update all the matches, which is a risky and slow process.

I'm thinking about an identifier that could be embedded in certain JavaDoc tags, so that it's easy for the IDE to detect which paragraphs are supposed to be the same, regardless of their location. This would allow a kind of re-factoring at the JavaDoc level.
 
Winston Gutkowski
Bartender
Posts: 10575
66
Eclipse IDE Hibernate Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Avor Nadal wrote:But I could go further and make this need extensible to several classes. For example, I've many EJBs which may throw the same type of exception, because of the same reason. This means that the descriptions of their @throw tags are exactly the same. If I want to do a small change, I've to run a search & replace to update all the matches, which is a risky and slow process.

It's an unfortunate fact that we don't have as many tools for "refactoring" documentation as we do for programs, so I do sympathise.

However, might it not be possible to put this information in your Exception class? Or - possibly even better - in the constructor method that you generally use?

Then your @throws tag could simply be something like:
  * @throws MyEJBException as described {@link MyEJBException#MyEJBException(String, int, double) here}.

I'm thinking about an identifier that could be embedded in certain JavaDoc tags, so that it's easy for the IDE to detect which paragraphs are supposed to be the same, regardless of their location. This would allow a kind of re-factoring at the JavaDoc level.

Possibly, but TBH I'd prefer to see this done as part of a coordinated project to improve Javadoc itself, rather than on a piecemeal basis by individual programmers.

And maybe it's time it was. Javadoc - wonderful as it is - hasn't really been "revisited" for quite a while.

Winston
 
Avor Nadal
Ranch Hand
Posts: 156
Java Netbeans IDE Postgres Database
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Winston Gutkowski wrote:
I should add that it's by no means the only solution, but it seems to fit this particular example.


That's why I fear my own examples, he he he. I'm sorry but that was just an artificial example. I should have used an existing API for the demonstration, so that the reader didn't focus on the domain instead of the background problem. For example, maybe a better example had been this one:



Really I just wanted to put a case in which you need some auxiliary variables to prepare the object that you're interested on. This happens very often and, in some case,s it's tiring to create a method just to encapsulate 2 or 3 lines.

PS: I know, I tend to use many explaining (temporary) variables. But I believe that they can help to programmers with less experience.
 
Winston Gutkowski
Bartender
Posts: 10575
66
Eclipse IDE Hibernate Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Avor Nadal wrote:Really I just wanted to put a case in which you need some auxiliary variables to prepare the object that you're interested on. This happens very often and, in some case,s it's tiring to create a method just to encapsulate 2 or 3 lines.

Again, I sympathise. And I will concede that for a moderate-sized method - say, 20 or 30 lines of code - it can be easier to follow if all the information is in one place.
However, it's definitely a law of diminishing return as size increases.

I'd also add two absolute stipulations :
1. The code is question is NEVER repeated anywhere else.
2. Every effort is made to name those variables well.

And BTW, you do realise that your example could be shortened by simply re-ordering it, viz:

Winston
 
Avor Nadal
Ranch Hand
Posts: 156
Java Netbeans IDE Postgres Database
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

However, might it not be possible to put this information in your Exception class? Or - possibly even better - in the constructor method that you generally use?

Then your @throws tag could simply be something like:
* @throws MyEJBException as described {@link MyEJBException#MyEJBException(String, int, double) here}.


Good idea. I tried to avoid so many "jumps" between explanations because I thought that someone could consider it a bad practice. But if you and other people think that it's acceptable, then I could implement it very easily.

There is an issue, related to this one, that I also would like to comment about. But better in its own thread...


And BTW, you do realise that your example could be shortened by simply re-ordering it, viz:


Yes, you're right. But I did it on purpose ;) . I put the most important variable of the block at the beginning because of 2 reasons:

1. To emphasise that that's what I'm trying to build in that block of code, without needing to read until the last line.
2. So that the following variables have a more specific context and can be named with shorter names.

I know that both things are what we get if we use methods instead of blocks, he he he. But again, I only would do this very sparsely.

By the way, I took this approach from StackOverflow, from an answer to certain question. However, I can't remember which one :/ .
 
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!