NetBeans 6 delivers great updates to the Matisse GUI builder. Spend a few minutes with Roman Strobl and get an expert briefing on what's new and what has changed. (sponsored)
In this, the third and final installation of Andres' Introduction to Groovy series, you learn about how Groovy handles variable numbers of arguments, named parameters, currying, and more about Groovy operators. Including, some new operators.
Swing Fuse (actually just Fuse), is a framework designed to make it easier to create your own custom desktop components. In this article, Daniel Spiewak shows you how to get started and provides sample source code you can download.
Willam Louth shows how he uses JXInsight Probes to investigate probable performance issues with code bases that he is not familiar with. He also highlights possible pitfalls in creating a benchmark, as well as in the analysis of results.
Replies:
26 -
Pages:
2
[
12
| Next
]
Threads:
[
Previous
|
Next
]
I'm not going to recommend you read all the books you can get your hands on, though you could if you wanted to. These are the tips they don't teach you in books or in school. From deleting code and refusing to comment, to deliberately throwing exceptions, these tidbits of experience will make you a faster and smarter developer. And that's what you want, right? Read on.
Make it simple
1: Delete delete delete
If a method or chunk of code, or even a whole class is not used, don't comment it out, just delete it, you won't need it later. I'm not kidding. In the incredibly rare case you do, you will remember how it works but write it a little more simply. And if something went horribly wrong, you have version control. The improvements in readability and understanding, and reduced test cases for test code that isn't called, more than saves the time you might lose in having to pull it out of your version control system. You are using version control, right?
2: Don't document complex code. Write clear code.
Ironically, this is one of the things you hear a lot of "make sure you document code that's hard to understand". Question: why write code that is hard to understand?
All of the time you spend on simplifying your code will equal the time you would spend on documentation and reduce the time you spend relearning the code if you have to make changes later (which you will).
Use long variable and method names if you want to, and put your code chunks into very short methods. For instance, in a 50+ line method this was one of the small snippets of code that was really unrelated to a lot of other stuff that happened within the method:
// up the version
version = oldRecord.getVersion();
if (version == -1) {
newRecord.setVersion(1);
} else {
newRecord.setVersion(version + 1);
}
A poor developer might have to spend a more than a few minutes devising an intricate test data set to ensure this was working correctly given that it's buried inside another method. The way we might do it, is to create a new method, with the snippet above, and having the below snippet instead:
updateVersionOnNewRecord(oldRecord, newRecord);
That will take you about 2-3 minutes to achieve, and you get code that is really easy to test, easy to understand, and what's more is that you'll find yourself reusing the method in other places.
3: Don't write comments - write log entries instead ..
And if you have to use comments, instead of using comments like "uber algorithm below", make it a log trace entry. Documentation is notorious for being neglected when code is being developed. It's psychologically much more pertinent when developing code to keep the log trace entry in sync with the code, and it kills two birds with one stone (you get documentation AND you get logging!). If you find this aversion to commenting a little difficult to grasp because you've seen code that was too difficult to understand without the comments, perhaps the code needs refactoring as to the Law of Demeter (below).
I will add one caveat -- comments can indeed be useful, especially when referencing externally defined algorithms and so on.
4: Use the Law of Demeter (for functions) to make your code simple
This law states that any method of an object should call only methods belonging to:
itself
any parameters that were passed into the method,
any objects created inside the method, and,
anything directly held by the object.
Read the above again. I'm not saying it's easy to follow or that you'll automatically do it first time, though if you keep it in mind writing a few blocks of code, within a few days, I know you will find yourself subconsciously writing better quality code.
5: Don't Repeat Yourself (DRY)
Duplication is bad. If you have more than 4-5 lines of code that do the same thing in a single class, it is quite possible that you could refactor to remove duplication. It might seem hard to refactor with the code intertwined. Test cases & version control will save you from that fear. If you can see that you would be able to refactor but theres just one or two lines of code that is different in each method that causes you trouble, you may be able to benefit from reflection or use of the Strategy pattern. Don't be afraid to ask for advice, chances are that it is possible and you can learn some neat new tricks in the process.
By the way, this applies not only to code, but to other resources, like images. For instance, keeping one master image, and automatically generating thumbnails from the master with a script is going to save a lot more time than manually opening your image editor.
No surprises please!
6: Deliberately break things that are partially completed
If you haven't implemented a method on an interface, or haven?t completed a section of code, add an UnsupportedOperationException with a good description. Anyone who uses your code now will know exactly what the problem is, allowing them to continue work save time chasing up a random exception that doesn't make sense. It also provides an easy marker for you to look through and find stuff you?ve missed.
7: Check your assumptions in code (fail-fast)
Put your hands up if you?ve ever written some code and wondered where the NullPointerException really came from? I think we all have.
Check your assumptions, and don't be afraid of throwing IllegalArgumentException. For example, if you get passed an array, check that the array has how many elements you think it should. If it doesn't, you should throw an exception with a clear description. It will take a few seconds to write but you can guarantee if a bug pops up you can much more easily identify the cause and location.
I hope you enjoyed this as much as I did. Leave your comments below or on my blog. This is Part One of the article and I hope to get Part Two out some time "soon".
About the author
Jason is a developer particularly interested in quality design and implementations for software problems. He has a wealth of experience in the telecommunications and Defence industries. He has just started a blog which can be read http://www.bluedevel.com/blog/ .
Hi JasonK, great tips. There is just one where I do not agreed. Don't write comments, write clear code.
If you are developing some app, yes, u are totally right, writing clear is enough, but if you are developing a framework, some API, you need to comment your code. That is very important. I have made a lot of things with Java2D and those comments help me out a lot.
I would always add the following though (blatantly plagarised from Elements of Java Style - a book that should be mandatory reading for all Java developers on pain of death):
KISS (Keep It Simple Stupid) - avoid the temptation to make something more complex than it needs to be, it can always be refactored later as necessary. i.e. avoid excessive use of patterns, third-party frameworks, overly complex hierarchies, etc. where a simple and clear design/implementation will suffice.
Perhaps the above is a more general guidelines for your points #2 and #4.
"It is impossible to make anything foolproof, because fools are so ingenious."
Interesting, especially the suggesting on "logging" vs. "commenting".
I'd also suggest never using inheritance for code-reuse. Design to delegate to separate reusable objects or utility classes first, and only inherit as a last resort if your class needs to be cast as a parent object for use elsewhere (the classic "is a" rule), and limit depth to 3 levels (less is better).
And don't override a method unless it's declared abstract, otherwise later on you (or more likely someone else) will waste a lot of time trying to figure out why this or that piece of code isn't getting executed even though "it's called right there" in the code, and getting lost down a rabbit hole.
I would just make one caveat regarding comments. I generally don't find comments that explain what the code is doing very useful (the code should already tell me that), but I've often found code explaining why the code is doing what it's doing, or why it's being done a specific way useful.
Other than that, I think this might become mandatory reading for my team.
I think you've got a good list there. These items should be something that every developer is aware of.
My personal favourite (or is it pet peeve?) is item 1 - "Delete delete delete". Looking at large amounts of commented out code drives me mad! Version control (and version histories in modern IDEs) provides functionality to go back to older versions of code so there shouldn't be any reason for not deleting old unused code.
The only other point I would add is keeping methods to a reasonable size. If I can't read the entire code for a method in one screen then I usually think that its too long.
> KISS (Keep It Simple Stupid) - avoid the temptation
> to make something more complex than it needs to be,
> it can always be refactored later as necessary. i.e.
> avoid excessive use of patterns, third-party
> frameworks, overly complex hierarchies, etc. where a
> simple and clear design/implementation will suffice.
clap, clap, clap, clap, clap
There is nothing more frustrating than having to dig through multiple levels of indirection to understand code that doesn't really need them.
Speaking for myself, I usually only see when I need patterns and complex hierarchies after some use of the code. There is nothing wrong with refactoring if you develop incrementally.
One of the things that really annoys me is constantly having to educate (sometimes experienced) developers as to what constitutes best practice.
Perhaps what the Java community needs is a centralised wiki or something detailing best practice at the various levels (architecture, design, implementation, process), drawn from the various books, web sites, articles such as the above, etc. Developers of all levels of experience could then be simply pointed to this resource.
Does anyone know of such a thing?
- chris
"It is impossible to make anything foolproof, because fools are so ingenious."
I disagree completely with the above, here are my guidelines...
1. General guidelines
Code clarity guidelines:
- white-space and blank lines eat up precious disc space on your development machine, therefore avoid using white-space in source code.
- good code should be self-documenting, therefore avoid using JavaDoc or in-code comments
- ensure that EVERY method is public, you never know when it will be needed elsewhere
Variable Scope
- declaring local variables at their point of usage is bad practice, ensure that all variables are declared at the top of a method (C style)
(this is particularly useful when a method extends over several screens).
Miscellaneous
- the time you have to spend typing is the most important factor to consider when developing software, cut-and-paste can save considerable effort in this area
- deep class hierarchies are a mark of good software design, therefore ensure that ALL classes extend from some base class
- interfaces cannot contain implementation therefore are redundant
- ensure that all existing code is re-factored to use Java 1.5 features (and soon 1.6) before beginning new implementation work
2. Naming Conventions
Variables and method names take up lots of memory space and require lots of typing (avoid using new-fangled IDEs).
Therefore ensure:
- identifiers are as short and ambiguous as possible
- omit vowels
- ideally use Hungarian Notation
- prefix all class members with m_
e.g.
int o;
String m_sPswd;
boolean fIsntNotDone;
3. Exception Handling
Exceptions are a poorly understood aspect of the Java language.
Therefore follow these guidelines:
- create a new (empty) checked exception for EVERY possible error condition
- log EVERY exception at EVERY layer of your application
- also dump ALL exceptions to the console to be doubly sure
- catch and rethrow ALL checked exceptions
- when re-throwing, ensure that the stack-trace is omitted
- always include a catch-all exception handler (i.e. catch Exception)
- ignore exceptions that you do not expect or understand
This generates a lot of exception handling code and new classes that will enhance the enterprise nature of your application.
Also the chances of missing an exception when diagnosing a fault are reduced as the stack-trace will be spread across all your logs.
e.g.
class MyException extends Exception {
public MyException( String msg ) {
super( msg );
}
}
public void someMethod() throws MyException, ServiceException, SQLException, IOException, RemoteException, LocalException, Exception {
try {
...
}
catch( ServiceException e ) {
log.error( "An exception occured", e );
e.printStackTrace();
throw new MyException( e.getMessage() );
}
catch( NullPointerException e ) {
// This shouldnt happen!
//e.printStackTrace();
}
catch( Exception e ) {
System.err.println( "Exception!" );
e.printStackTrace();
log.error( e );
throw new MyException( "An exception happened in someMethod()" );
}
}
4. Defensive Programming
GIGO (Garbage In, Garbage Out) is poor practice. Therefore code should 'fix' any illegal conditions thus ensuring that errors in the system
are not manifested during development (any bugs can be resolved by maintenance when your system goes live).
Poor practice:
public void method( SomeThing thing, int min ) {
if( thing == null ) throw new IllegalArgumentException( "Thing is null" );
if( min < MINIMUM ) throw new IllegalArgumentException( "Minimum out of range: " + min );
...
}
Best practice:
public void method( SomeThing thing, int min ) {
if( thing == null ) {
thing = FactoryFactory.getInstance().getFactory().newThing();
}
if( min < 42 ) min = 42;
...
}
"It is impossible to make anything foolproof, because fools are so ingenious."
7 Top Tips for Quality Java Software
At 3:07 AM on Sep 24, 2007, jasonk wrote:
Fresh Jobs for Developers Post a job opportunity
Make it simple
1: Delete delete delete
If a method or chunk of code, or even a whole class is not used, don't comment it out, just delete it, you won't need it later. I'm not kidding. In the incredibly rare case you do, you will remember how it works but write it a little more simply. And if something went horribly wrong, you have version control. The improvements in readability and understanding, and reduced test cases for test code that isn't called, more than saves the time you might lose in having to pull it out of your version control system. You are using version control, right?
2: Don't document complex code. Write clear code.
Ironically, this is one of the things you hear a lot of "make sure you document code that's hard to understand". Question: why write code that is hard to understand?
All of the time you spend on simplifying your code will equal the time you would spend on documentation and reduce the time you spend relearning the code if you have to make changes later (which you will).
Use long variable and method names if you want to, and put your code chunks into very short methods. For instance, in a 50+ line method this was one of the small snippets of code that was really unrelated to a lot of other stuff that happened within the method:
// up the version version = oldRecord.getVersion(); if (version == -1) { newRecord.setVersion(1); } else { newRecord.setVersion(version + 1); }A poor developer might have to spend a more than a few minutes devising an intricate test data set to ensure this was working correctly given that it's buried inside another method. The way we might do it, is to create a new method, with the snippet above, and having the below snippet instead:
updateVersionOnNewRecord(oldRecord, newRecord);
That will take you about 2-3 minutes to achieve, and you get code that is really easy to test, easy to understand, and what's more is that you'll find yourself reusing the method in other places.
3: Don't write comments - write log entries instead ..
And if you have to use comments, instead of using comments like "uber algorithm below", make it a log trace entry. Documentation is notorious for being neglected when code is being developed. It's psychologically much more pertinent when developing code to keep the log trace entry in sync with the code, and it kills two birds with one stone (you get documentation AND you get logging!). If you find this aversion to commenting a little difficult to grasp because you've seen code that was too difficult to understand without the comments, perhaps the code needs refactoring as to the Law of Demeter (below).
I will add one caveat -- comments can indeed be useful, especially when referencing externally defined algorithms and so on.
4: Use the Law of Demeter (for functions) to make your code simple
This law states that any method of an object should call only methods belonging to:
Read the above again. I'm not saying it's easy to follow or that you'll automatically do it first time, though if you keep it in mind writing a few blocks of code, within a few days, I know you will find yourself subconsciously writing better quality code.
5: Don't Repeat Yourself (DRY)
Duplication is bad. If you have more than 4-5 lines of code that do the same thing in a single class, it is quite possible that you could refactor to remove duplication. It might seem hard to refactor with the code intertwined. Test cases & version control will save you from that fear. If you can see that you would be able to refactor but theres just one or two lines of code that is different in each method that causes you trouble, you may be able to benefit from reflection or use of the Strategy pattern. Don't be afraid to ask for advice, chances are that it is possible and you can learn some neat new tricks in the process.
By the way, this applies not only to code, but to other resources, like images. For instance, keeping one master image, and automatically generating thumbnails from the master with a script is going to save a lot more time than manually opening your image editor.
No surprises please!
6: Deliberately break things that are partially completed
If you haven't implemented a method on an interface, or haven?t completed a section of code, add an UnsupportedOperationException with a good description. Anyone who uses your code now will know exactly what the problem is, allowing them to continue work save time chasing up a random exception that doesn't make sense. It also provides an easy marker for you to look through and find stuff you?ve missed.
7: Check your assumptions in code (fail-fast)
Put your hands up if you?ve ever written some code and wondered where the NullPointerException really came from? I think we all have.
Check your assumptions, and don't be afraid of throwing IllegalArgumentException. For example, if you get passed an array, check that the array has how many elements you think it should. If it doesn't, you should throw an exception with a clear description. It will take a few seconds to write but you can guarantee if a bug pops up you can much more easily identify the cause and location.
I hope you enjoyed this as much as I did. Leave your comments below or on my blog. This is Part One of the article and I hope to get Part Two out some time "soon".
About the author
Jason is a developer particularly interested in quality design and implementations for software problems. He has a wealth of experience in the telecommunications and Defence industries. He has just started a blog which can be read http://www.bluedevel.com/blog/ .
26 replies so far (
Post your own)
Re: Top tips For Quality Java Software
Hi JasonK, great tips. There is just one where I do not agreed. Don't write comments, write clear code.If you are developing some app, yes, u are totally right, writing clear is enough, but if you are developing a framework, some API, you need to comment your code. That is very important. I have made a lot of things with Java2D and those comments help me out a lot.
great post. best regards.
Rodrigo
Re: 7 Top Tips for Quality Java Software
Great stuff. I printed this post and kept it at my desk. Also, I gave some copies to my coworkersI would add one more tip (which saved us tons of money): Don't use global variables (or even singletons) use context programming instead!
-- Javolution: Everything should be made as simple as possible... -- JScience: But not simpler!
Re: 7 Top Tips for Quality Java Software
Good stuff.I would always add the following though (blatantly plagarised from Elements of Java Style - a book that should be mandatory reading for all Java developers on pain of death):
KISS (Keep It Simple Stupid) - avoid the temptation to make something more complex than it needs to be, it can always be refactored later as necessary. i.e. avoid excessive use of patterns, third-party frameworks, overly complex hierarchies, etc. where a simple and clear design/implementation will suffice.
Perhaps the above is a more general guidelines for your points #2 and #4.
Re: 7 Top Tips for Quality Java Software
Interesting, especially the suggesting on "logging" vs. "commenting".I'd also suggest never using inheritance for code-reuse. Design to delegate to separate reusable objects or utility classes first, and only inherit as a last resort if your class needs to be cast as a parent object for use elsewhere (the classic "is a" rule), and limit depth to 3 levels (less is better).
And don't override a method unless it's declared abstract, otherwise later on you (or more likely someone else) will waste a lot of time trying to figure out why this or that piece of code isn't getting executed even though "it's called right there" in the code, and getting lost down a rabbit hole.
Re: 7 Top Tips for Quality Java Software
I would just make one caveat regarding comments. I generally don't find comments that explain what the code is doing very useful (the code should already tell me that), but I've often found code explaining why the code is doing what it's doing, or why it's being done a specific way useful.Other than that, I think this might become mandatory reading for my team.
Re: 7 Top Tips for Quality Java Software
I think you've got a good list there. These items should be something that every developer is aware of.My personal favourite (or is it pet peeve?) is item 1 - "Delete delete delete". Looking at large amounts of commented out code drives me mad! Version control (and version histories in modern IDEs) provides functionality to go back to older versions of code so there shouldn't be any reason for not deleting old unused code.
The only other point I would add is keeping methods to a reasonable size. If I can't read the entire code for a method in one screen then I usually think that its too long.
Re: 7 Top Tips for Quality Java Software
> KISS (Keep It Simple Stupid) - avoid the temptation> to make something more complex than it needs to be,
> it can always be refactored later as necessary. i.e.
> avoid excessive use of patterns, third-party
> frameworks, overly complex hierarchies, etc. where a
> simple and clear design/implementation will suffice.
clap, clap, clap, clap, clap
There is nothing more frustrating than having to dig through multiple levels of indirection to understand code that doesn't really need them.
Speaking for myself, I usually only see when I need patterns and complex hierarchies after some use of the code. There is nothing wrong with refactoring if you develop incrementally.
Re: 7 Top Tips for Quality Java Software
8: Wrap Checked Exceptions as Runtime Exceptions and rethrow.http://philswenson.com
Re: 7 Top Tips for Quality Java Software
Good points every one!Re: 7 Top Tips for Quality Java Software
This is all really good stuff.One of the things that really annoys me is constantly having to educate (sometimes experienced) developers as to what constitutes best practice.
Perhaps what the Java community needs is a centralised wiki or something detailing best practice at the various levels (architecture, design, implementation, process), drawn from the various books, web sites, articles such as the above, etc. Developers of all levels of experience could then be simply pointed to this resource.
Does anyone know of such a thing?
- chris
Re: 7 Top Tips for Quality Java Software
I disagree completely with the above, here are my guidelines...1. General guidelines
Code clarity guidelines:
- white-space and blank lines eat up precious disc space on your development machine, therefore avoid using white-space in source code.
- good code should be self-documenting, therefore avoid using JavaDoc or in-code comments
- ensure that EVERY method is public, you never know when it will be needed elsewhere
Variable Scope
- declaring local variables at their point of usage is bad practice, ensure that all variables are declared at the top of a method (C style)
(this is particularly useful when a method extends over several screens).
Miscellaneous
- the time you have to spend typing is the most important factor to consider when developing software, cut-and-paste can save considerable effort in this area
- deep class hierarchies are a mark of good software design, therefore ensure that ALL classes extend from some base class
- interfaces cannot contain implementation therefore are redundant
- ensure that all existing code is re-factored to use Java 1.5 features (and soon 1.6) before beginning new implementation work
2. Naming Conventions
Variables and method names take up lots of memory space and require lots of typing (avoid using new-fangled IDEs).
Therefore ensure:
- identifiers are as short and ambiguous as possible
- omit vowels
- ideally use Hungarian Notation
- prefix all class members with m_
e.g.
int o;
String m_sPswd;
boolean fIsntNotDone;
3. Exception Handling
Exceptions are a poorly understood aspect of the Java language.
Therefore follow these guidelines:
- create a new (empty) checked exception for EVERY possible error condition
- log EVERY exception at EVERY layer of your application
- also dump ALL exceptions to the console to be doubly sure
- catch and rethrow ALL checked exceptions
- when re-throwing, ensure that the stack-trace is omitted
- always include a catch-all exception handler (i.e. catch Exception)
- ignore exceptions that you do not expect or understand
This generates a lot of exception handling code and new classes that will enhance the enterprise nature of your application.
Also the chances of missing an exception when diagnosing a fault are reduced as the stack-trace will be spread across all your logs.
e.g.
class MyException extends Exception {
public MyException( String msg ) {
super( msg );
}
}
public void someMethod() throws MyException, ServiceException, SQLException, IOException, RemoteException, LocalException, Exception {
try {
...
}
catch( ServiceException e ) {
log.error( "An exception occured", e );
e.printStackTrace();
throw new MyException( e.getMessage() );
}
catch( NullPointerException e ) {
// This shouldnt happen!
//e.printStackTrace();
}
catch( Exception e ) {
System.err.println( "Exception!" );
e.printStackTrace();
log.error( e );
throw new MyException( "An exception happened in someMethod()" );
}
}
4. Defensive Programming
GIGO (Garbage In, Garbage Out) is poor practice. Therefore code should 'fix' any illegal conditions thus ensuring that errors in the system
are not manifested during development (any bugs can be resolved by maintenance when your system goes live).
Poor practice:
public void method( SomeThing thing, int min ) {
if( thing == null ) throw new IllegalArgumentException( "Thing is null" );
if( min < MINIMUM ) throw new IllegalArgumentException( "Minimum out of range: " + min );
...
}
Best practice:
public void method( SomeThing thing, int min ) {
if( thing == null ) {
thing = FactoryFactory.getInstance().getFactory().newThing();
}
if( min < 42 ) min = 42;
...
}
Re: 7 Top Tips for Quality Java Software
Chris, Great guidelines!I which more people followed them.. Constructing largescale systems would be so much more fun and exiting then!
Re: 7 Top Tips for Quality Java Software
Ohh... But enough people already do, they do...Re: 7 Top Tips for Quality Java Software
I hope this is a joke,All your points are bad, so I expect you forgot the ;)))
at the end. Good one !