Saturday, 8 October 2016

- Use Exceptions Rather Than Return Codes

The problem with these approaches is that they clutter the caller. The caller must check for errors immediately after the call. Unfortunately, it’s easy to forget. For this reason
it is better to throw an exception when you encounter an error. The calling code is
cleaner. Its logic is not obscured by error handling.

- Provide Context with Exceptions

-Define Exception Classes in Terms of a Caller’s Needs
Often a single exception class is fine for a particular area of code. The information
sent with the exception can distinguish the errors. Use different classes only if there are
times when you want to catch one exception and allow the other one to pass through.

Define the Normal Flow
If you follow the advice in the preceding sections, you’ll end up with a good amount of separation between your business logic and your error handling. The bulk of your code will start to look like a clean unadorned algorithm. However, the process of doing this pushes error detection to the edges of your program. You wrap external APIs so that you can throw your own exceptions, and you define a handler above your code so that you can deal with any aborted computation. Most of the time this is a great approach, but there are some times when you may not want to abort.

This is called the SPECIAL CASE PATTERN [Fowler]. You create a class or configure an
object so that it handles a special case for you. When you do, the client code doesn’t have
to deal with exceptional behavior. That behavior is encapsulated in the special case object.

Don’t Return Null
If you are tempted to return null from
a method, consider throwing an exception or returning a SPECIAL CASE object instead

Friday, 7 October 2016

Objects and Data Structures

Objects expose behavior and hide data. This makes it easy to add new kinds of objects
without changing existing behaviors. It also makes it hard to add new behaviors to existing
objects. Data structures expose data and have no significant behavior. This makes it easy to
add new behaviors to existing data structures but makes it hard to add new data structures
to existing functions.
In any given system we will sometimes want the flexibility to add new data types, and
so we prefer objects for that part of the system. Other times we will want the flexibility to
add new behaviors, and so in that part of the system we prefer data types and procedures.
Good software developers understand these issues without prejudice and choose the
approach that is best for the job at hand.
Bibliography

[Refactoring]: Refactoring: Improving the Design of Existing Code, Martin Fowler et al.,
Addison-Wesley, 1999.

Wednesday, 5 October 2016

Mandated Comments

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, propagate lies, and lend to general confusion and disorganization.
For example, required javadocs for every function lead to abominations.This clutter adds nothing and serves only to obfuscate the code and create the potential for lies and misdirection.

/**
*
* @param title The title of the CD
* @param author The author of the CD
* @param tracks The number of tracks on the CD
* @param durationInMinutes The duration of the CD in minutes
*/
public void addCD(String title, String author,
int tracks, int durationInMinutes) {
CD cd = new CD();
cd.title = title;
cd.author = author;
cd.tracks = tracks;
cd.duration = duration;
cdList.add(cd);
}

Clean Code By Robert C. Martin
P63 Chapter 4: Comments

Tuesday, 4 October 2016

Command Query Separation


Functions should either do something or answer something, but not both. Either your
function should change the state of an object, or it should return some information about
that object. Doing both often leads to confusion. Consider, for example, the following
function:

public boolean set(String attribute, String value);

This function sets the value of a named attribute and returns true if it is successful and
false if no such attribute exists. This leads to odd statements like this:

if (set("username", "unclebob"))...

Imagine this from the point of view of the reader. What does it mean? Is it asking whether
the “username” attribute was previously set to “unclebob”? Or is it asking whether the
“username” attribute was successfully set to “unclebob”? It’s hard to infer the meaning from
the call because it’s not clear whether the word “set” is a verb or an adjective.

The author intended set to be a verb, but in the context of the if statement it feels like
an adjective. So the statement reads as “If the username attribute was previously set to
unclebob” and not “set the username attribute to unclebob and if that worked then. . . .” We
could try to resolve this by renaming the set function to setAndCheckIfExists, but that
doesn’t much help the readability of the if statement. 

The real solution is to separate the command from the query so that the ambiguity cannot occur.

if (attributeExists("username")) {
setAttribute("username", "unclebob");
...
}

Clean Code By Robert C. Martin
46 Chapter 3: Functions