Best Practices. Contents Bad Practices Good Practices.
-
Upload
emory-glenn -
Category
Documents
-
view
268 -
download
0
Transcript of Best Practices. Contents Bad Practices Good Practices.
Best Practices
Contents
• Bad Practices• Good Practices
Bad PracticesBad Practices
Duplicate Code!
• Every time you need to make a change in the routine, you need to edit it in several places.
–Called “Shotgun Surgery”.
• Follow the “Once and Only Once” rule.
• Don’t copy-paste code!
Accessible Fields
• Fields should always be private except for constants.
• Accessible fields cause tight coupling.
• Accessible fields are corruptible.
• If a field needs to be accessed, use “get” and “set” convention.
Using Magic Numbers
• Magic numbers are not readable, and can lead to “Shotgun Surgery”.
for (int i = 1; i =< 52; i++) {j = i + randomInt(53 - i) – 1swapEntries(i, j)
}• Replace with constants.
final int DECKSIZE = 52;for (int i = 1; i =< DECKSIZE; i++) {
j = i + randomInt(DECKSIZE + 1 - i) – 1swapEntries(i, j)
}
Temporary Fields
• If a variable need not be shared across methods, make it local.
private int x;int method() {
x = 0; // if you forget to initialize, you're dead... // do some stuffreturn x;
}
int method() {int x = 0;... // do some stuffreturn x;
}
Initializing Strings with “new”
• Don’t:String str = new String(“This is bad.”);
• Do:String str = “This is good.”;
Using floats and doubles for currency calculations
• Binary numbers cannot exactly represent decimals.
• Use BigDecimal for currency calculations.– ...using the constructor that takes a
String as a parameter.
Returning null
• Causes NullPointerExceptions.
• Instead, return…– empty objects
– custom-made “Null Objects”
Subclassing for Functionality
• Implementation inheritance is difficult to debug.
• Ask yourself: “Is this a kind of…?”
• Alternatives:– Prefer interface inheritance.– Prefer composition over inheritance.
Empty Catch Block
• No indication that an exception has occurred!
Using Exceptions Unexceptionally
• Use exceptions only for exceptional conditions.
• Bad:try {
obj = arr[index];} catch (ArrayIndexOutOfBoundsException) {
// do something}
• Good:if (index < 0 || index >= arr.size()) {
// do something} else {
obj = arr[index];}
Excessive Use of Switches
• Use of “if” and “switch” statements usually a sign of a breach of the “One Responsibility Rule”.
• Consider polymorphism instead.
instanceof
• If you’re using instanceof often, it probably means bad design.
• Consider adding an overridden method in supertype.
• instanceof should only be used – as validation prior to casting– when you have to used a poorly-written library
Static Methods
• Static methods are..– ...procedural
• They break encapsulation - the method should be part of the object that needs it
– ...not polymorphic• You can't have substitution/pluggability.
– You can't override a static method because the implementation is tied to the class it's defined in.
• Makes your code rigid, difficult to test.
System.exit
• Only use in stand-alone applications.• For server applications, this might shut down
the whole application container!
Good PracticesGood Practices
Validate Your Parameters
• The first lines of code in a method should check if the parameters are valid:
void myMethod(String str, int index, Object[] arr) { if (str == null) {
throw new IllegalArgumentException(“str cannot be null”);
} if (index >= arr.size || index < 0) { throw new IllegalArgumentException(“index exceeds
bounds of array”); } …}
Create Defensive Copies
• Create local copies, to prevent corruption.
void myMethod (List listParameter) {List listCopy = new ArrayList(listParameter);listCopy.add(somevar);...
}
Modify Strings with StringBuilder
• String objects are immutable.– You may think you’re changing a
String, but you’re actually creating a new object.–Danger of OutOfMemoryErrors.– Poor peformance.
• StringBuilder is mutable.– All changes are to the same object.
Favor Immutability
• If your objects don’t change… easier to debug.
• Fields are private and final.
• No setters, only getters.
Prefer “final” for Variables
• Usually, variables / parameters do not need to change.
• Get into the habit of using final by default, and make a variable not final only when necessary.
Declare Variable Just Before Use
• Easier to read and refactor.
Initialize Variables Whenever Possible
• Helpful in debugging, makes it clear what initial value is.
• Makes sure you don’t use the variable before it’s ready for use.
Follow Code Conventions
• Improves readability– For other programmers.– For yourself.
• Readability means… –…less bugs.–…easier to debug.
Refer to Objects by Interfaces
• Maintainability - changes in implementation need only be done at a single point in code
• Polymorphism – implementation can be set at runtime.
// bad:ArrayList list = new ArrayList();list.add(somevar);
// good:List list = new ArrayList();list.add(somevar);
Consider Using Enums instead of Constants
• Constants:–Not typesafe–No namespace
• You often need to prefix constants to avoid collisions
– Brittleness• When you change the order, you need to change
a lot of code.– Printed values are uninformative
Buffer I/O Streams
• Requesting OS for I/O resources is expensive.• Buffering provides significant increase in
performance.
Close Your I/O Streams
• If you don’t close, other applications may not be able to use the resource.
• Close using the “finally” block in a try-catch.
Design Close to Domain
• Code is easily traceable if it is close to the business it is working for.
• If possible, name and group your packages according to the use cases.– Easy to tell client %completion of feature.– If user reports a bug, easier to find where it is.
If You Override equals() Override hashcode()
• Always make sure that when equals() returns true, the two object have the same hashcode.
• Otherwise, data structures like Sets and Maps may not work.
• There are many IDE plug-ins and external libraries that can help you with this.
Write Self-Documenting Code
• Comments are important, but…
• …even without comments your code should be easily readable.
• Ask yourself: “If I removed my comments, can someone else still understand my code?”
Use Javadoc Liberally
• Provide as much documentation about your code as possible.
Bubble-Up Exceptions
• If code is not part of the user interface, it should not handle its own exceptions.
• It should be bubbled-up to presentation layer…
• Show a popup?• Show an error page?• Show a commandline message?• Just log to an error log?
References
• “Effective Java” by Joshua Bloch• Refactoring by Martin Fowler• http://javapractices.com