Tuesday, September 29, 2009

Groovy JDK (GDK): Number Support

The Groovy JDK (GDK) provides several convenience methods related to numbers as part of its Number class extension. All of the numeric classes that extend Number inherit these methods.

The following Groovy script demonstrates use of several of the convenience methods on the GDK's Number class.


numberPi = Math.PI
numberE = Math.E
negativeFifteen = -15
positiveTen = 10
zero = 0
println "$numberPi is a ${numberPi.getClass().name}"
println "$numberE is a ${numberE.getClass().name}"
println "$negativeFifteen is a ${negativeFifteen.getClass().name}"

println "\n===== Number.abs() ====="
println "Number.abs() for $negativeFifteen: ${negativeFifteen.abs()}"

println "\n===== Number.downto(Number, Closure) ====="
positiveTen.downto(1) {println "$it / 2 = ${it / 2}"}

println "\n===== Number.upto(Number, Closure) ====="
zero.upto(5) {println "$it * 5 = ${it * 5}"}

println "\n===== Number.times(Closure) ====="
3.times() {print it}
println ""

println "\n===== Number.power(Number) ====="
println "5.power(2) = ${5.power(2)}"
println "5**2 = ${5**2}"

println "\n===== Number.multiply(Number) ====="
println "5.multiply(3) = ${5.multiply(3)}"
println "5*3 = ${5*3}"

println "\n===== Number.div(Number) ====="
println "25.div(5) = ${25.div(5)}"
println "25/5 = ${25/5}"

println "\n====== Number.intdiv(Number) ====="
println "13intdiv(2) = ${13.intdiv(2)}"
println "(int) (13/2) = ${(int) (13/2)}"

println "\n===== Number.plus(Number) ====="
println "1.1.plus(0.2) = ${1.1.plus(0.2)}"
println "1.1 + 0.2 = ${1.1 + 0.2}"

println "\n===== Number.plus(String) ====="
println "10.plus('Four'): ${10.plus('Four')}"
println "10 + 'Four': ${10 + 'Four'}"

println "\n===== Number.minus(Number) ====="
println "10.0.minus(9.9) = ${10.0.minus(9.9)}"
println "10.0 - 9.9 = ${10.0 - 9.9}"

println "\n===== Number.mod(Number) ====="
println "11.mod(2) = ${11.mod(2)}"
println "11 % 2 = ${11 % 2}"

println "\n===== Number.previous() ====="
println "11.previous() = ${11.previous()}"
println "--11 = ${--11}"

println "\n===== Number.next() ====="
println "5.5.next() = ${5.5.next()}"
println "++5.5 = ${++5.5}"

println "\n===== Number.leftShift(Number) ====="
println "8.leftShift(3) = ${8.leftShift(3)}"
println "8 << 3 = ${8 << 3}"

println "\n===== Number.rightShift(Number) ====="
println "8.rightShift(3) = ${8.rightShift(3)}"
println "8 >> 3 = ${8 >> 3}"


The output from the above script is shown in the next screen snapshots.





From the Groovy source code and its associated output, it is evident that the Groovy GDK provides many highly useful and convenient features. Among other things, the use of closures is demonstrated. Closures allow blocks of functionality to be passed as parameters to methods on the Number class.

The example above also demonstrates that the Groovy Number methods directly support the basic mathematical operators. Groovy code can either use these operators with their symbols or invoke the implementing named methods directly.

There are some nice "extras" in the Number class such as the absolute value method (abs()) and the closure-powered times() method. The leftShift() and rightShift() methods respectively provide numbers represented by left-shifting and right-shifting the underlying bits.

The Groovy JDK (GDK) provides the Groovy developer with many convenient methods. This blog posting has demonstrated only some of the convenient features exposed by the GDK's Number extension. In previous blog posts, I have covered other pieces of the GDK such as String, File generally, parsing File contents as String, and deleting a directory with the GDK File.

Monday, September 28, 2009

Groovy JDK (GDK): String Support

In previous blog postings on the Groovy JDK (GDK), I discussed use of GDK File functions such as File.deleteDir(), File.getText(), File.readLines(), File.setText(String)/File.write(String), File.append(Object), and File.size(). In this blog post, I move onto covering the GDK's extended String class.

The GDK's extended String class has numerous convenience methods. These methods provide functionality that can often be implemented in custom Java code, but is handily available with the Groovy JDK.

The String.count(String) method counts the number of occurrences of the String passed as a parameter that exist within the String upon which the count method is called. A similar method that the extended String provides is the String.contains(String) method, which indicates whether the String upon which the method is invoked contains the String passed to the method as a parameter. Both of these methods are demonstrated in the next code listing.


// Demonstrate GDK's String.count() and String.contains(String)
repeatedString = "yesornoyesornoyesorno"
substr = "yes"
println "Number of occurrences of '${substr}' in $repeatedString: ${repeatedString.count(substr)}"
println "$repeatedString contains '$substr'?: ${repeatedString.contains(substr)}"


The output from this Groovy script snippet is shown next.



The method String.replace(String,String) allows a specified substring in the String to be replaced with the second specified String. This is demonstrated in the next code listing and its accompanying output screen snapshot.


// Demonstrate GDK's String.replace(CharSequence,CharSequence)
newSubstr = "si"
println "Replacing '$substr' in '$repeatedString' with '$newSubstr': ${repeatedString.replace(substr,newSubstr)}"




The overloaded versions of String.center() can be highly useful. The following snippet of Groovy code demonstrates the behavior of this centering method using various parameters. Spaces are used to center the provided text by default, but other characters can be used to force the centering as shown in this next code listing and its accompanying output screen snapshot.


// Demonstrate GDK's String.center(Number) and String.center(Number,String)
// 1. Demonstrate center with more characters than String being centered
// 2. Demonstrate center with fewer characters than String being centered
// 3. Demonstrate center with negative number of characters
// 4. Demonstrate center with characters other than spaces ("Groovy")
centeredString = "Dustin"
println "Centered String: 1. ${centeredString.center(20)}"
println "Centered String: 2. ${centeredString.center(4)}"
println "Centered String: 3. ${centeredString.center(-1)}"
println "Centered String: 4. ${centeredString.center(25,"Groovy")}"




The String.multiply(Number) method allows the target String to be multiplied as many times as specified by the passed-in parameter and returned as a single String. This is demonstrated in the following code with its output.


// Demonstrate String.multiply(Number)
multipleCopies = 5
println "Multiply '$centeredString' by $multipleCopies: ${centeredString.multiply(multipleCopies)}"


The GDK String extension provides several different methods for indicating whether a given String is of a particular numeric type. These can be useful to call before calling corresponding methods that convert the provided Strings to numeric types as well. The methods for determining if a String is of a particular numeric type are demonstrated next and the output is shown after the code listing.


// Demonstrate String methods for testing types of numerics
numericValue = "15";
alphaValue = "abc";
println "Is '$numericValue' parseable as a BigDecimal? ${numericValue.isBigDecimal()}"
println "Is '$alphaValue' parseable as a BigDecimal? ${alphaValue.isBigDecimal()}"
println "Is '$numericValue' parseable as a BigInteger? ${numericValue.isBigDecimal()}"
println "Is '$alphaValue' parseable as a BigInteger? ${alphaValue.isBigDecimal()}"
println "Is '$numericValue' parseable as a Double? ${numericValue.isDouble()}"
println "Is '$alphaValue' parseable as a Double? ${alphaValue.isDouble()}"
println "Is '$numericValue' parseable as a Long? ${numericValue.isLong()}"
println "Is '$alphaValue' parseable as a Long? ${alphaValue.isLong()}"
println "Is '$numericValue' parseable as a Float? ${numericValue.isFloat()}"
println "Is '$alphaValue' parseable as a Float? ${alphaValue.isFloat()}"
println "Is '$numericValue' parseable as a Number? ${numericValue.isNumber()}"
println "Is '$alphaValue' parseable as a Number? ${alphaValue.isNumber()}"




The GDK String extension provides methods String.readLines() and String.toList() to convert between a single String and multiple Strings. The readLines() method returns each distinct line in the given String as its own entry in a List of Strings. The toList() method converts each character in the target String to an element of a List of one-character entries.


// Demonstrate String.readLines() functionality
multiLineString = "One\nTwo\nThree\nFour\nFive"
println "Multiline String: $multiLineString"
println "Multiline String List: ${multiLineString.readLines()}"

// Demonstrate String.toList()
singleString = "123456789"
println "'$singleString'.toList() is ${singleString.toList()}"




The String.reverse() method does exactly what you'd think: it returns a String with the characters in reverse order of the original String.


// Demonstrate String.reverse()
println "'$singleString'.reverse() is ${singleString.reverse()}"




The String.getAt(int) method is useful for getting a character out of a String based on a particular index.


// Demonstrate String.getAt(int)
charIndex = 3
println "Character at index $charIndex is $singleString: ${singleString.getAt(3)}"




The String.leftShift(Object) method enables the << operator to be used to concatenate Strings into an overall String (or more precisely, a StringBuffer).


// Demonstrate left shift operator (String.leftShift(Object))
part1 = "Hello"
part2 = "World"
part3 = "Example"
concatenatedString = "$part1" << "$part2" << "$part3"
println "Concatenating $part1, $part2, and $part3: $concatenatedString"
println "Type of concatenatedString: ${concatenatedString.getClass().name}"




The String.minus(Object) method allows the String representation of the parameter Object to be removed from the target String. As noted in the previous example, the resultant "String" from use of the String.leftShift() method is actually a StringBuffer. The GDK does not provide the minus() method on StringBuffer so I need to explicitly inform Groovy that I am using a String to demonstrate the minus method on the just-concatenated "String."


// Demonstrate String.minus(Object)
//
// Need to tell Groovy to treat concatenatedStringOverall as a String rather
// than as a StringBuffer to be able to call the "minus" method. Otherwise, the
// error message encountered is:
// Caught: groovy.lang.MissingMethodException: No signature of method:
// java.lang.StringBuffer.minus() is applicable for argument types:
// (java.lang.String) values: [Example]
String concatenatedActualString = concatenatedString
println "Minus $part3 from $concatenatedActualString: ${concatenatedActualString.minus(part3)}"




The last convenience method on the GDK extended String class that I want to demonstrate is the handy (several overloaded versions) String.execute() method. This method allow the target String to be executed against the underlying operating system. This is demonstrated with the next code listing, which employs a Windows-specific command to list the directory contents.


// Demonstrate String.execute()
directoryListing = "cmd /C dir"
println "Directory Listing: ${directoryListing.execute().text}"


The output will, of course, vary per system, but looks something like that shown next:



This blog posting has demonstrated several useful functions provided by the Groovy JDK (GDK) extended String class. However, there are even more methods provided by this class than shown here. Like the rest of the GDK, the extended String class adds great convenience for the developer.

Groovy JDK (GDK): More File Fun

In previous blog posts covering features in the Groovy JDK (GDK), I have focused on the GDK's File.getText() method and on the GDK's File.deleteDir() method. In this blog post, I look at additional functionality provided by GDK's extended File such as File.readLines(), File.setText(), and File.size().

The File.readLines() method easily returns the text contents of a given file similarly to the File.getText() method, but it returns these contents as a List of Strings with each String representing individual lines in the read-in file.

The following code snippet, a Groovy script called fileReadLines.groovy, demonstrates this Groovy function:


file = new File("TextFile.txt")
lines = file.readLines()
printf "$file's contents: $lines%n"
for (line in lines) printf "\t$line%n"


As in the previous blog posting, TextFile.txt is defined as shown below:


This is a text file.
This is only a text file.


When the above Groovy script, fileReadLines.groovy, is executed with the above text file, the results are as shown in the next screen snapshot.



As this output demonstrates, the returned list's contents can be displayed implicitly with square brackets or it can be iterated over to print each element in the list one-by-one.

Groovy JDK (GDK) makes writing text to a file as easy as reading it. The File.setText(String) method works as easily as the File.getText() method as demonstrated in the code listing below.


file = new File("TextOutputFile.txt")
file.setText("I am text looking for home.")


The output from this is shown in the next screen snapshot.



The Javadoc-based documentation for File.setText(String) reports that this method is a synonym for File.write(String). Note that both of these methods completely overwrite any existing text in the given file. If one wants to append new text to a file without obliterating existing text, the File.append(Object) method is useful.



Finally, GDK's File.size() method can be useful to see the file's size. The following code listing shows it.


file = new File("TextOutputFile.txt")
file.setText("I am text looking for home.")
file.append("I am also looking for a good home.")
printf "Size of file TextOutputFile.txt: ${file.size()}%n"


The output from running the above is shown next.




Conclusion

This blog post has demonstrated how easy it is to use File.setText(String) (and File.write(String)), File.append(Object), File.readLines(), and File.size(). These extensions to the standard JDK File make manipulation of files easier for Groovy scripts.

Thursday, September 24, 2009

Groovy JDK (GDK): Text File to String

In my previous blog post, I briefly talked about the advantages of Groovy JDK (GDK) and specifically illustrated this by demonstrating how the GDK's File.deleteDir() method provides additional functionality beyond that provided by the standard SDK File.delete(). In this blog post, I demonstrate how another GDK extension function, File.getText(), makes extracting text from a file practically trivial.

When one wants to extract text from a file into a Java String, a typical approach is to use a BufferedReader. In fact, this is demonstrated in various forms in resources such as Java Developers Almanac 1.4 (swallows checked IOException), reading lines from text file, Reading and Writing Text Files, and How Do I Read a Text File? The How to Read File in Java example uses BufferedInputStream and DataInputStream.

In all of these examples, there is significant code involved to handle checked exceptions and resource management. Java-based one-line alternatives are discussed in the blog post Java One Liner - Reading a Text File at Once. Groovy, via its GDK, makes extracting a String from a File simple and convenient. The following Groovy code demonstrates how easy this is to use.

fileGetText.groovy

file = new File("TextFile.txt")
printf "$file's contents: ${file.getText()}"


The content of the TextFile.txt file is as shown next:

TextFile.txt

This is a text file.
This is only a text file.


The following screen snapshot shows the results of running the simple Groovy code against this text file:



All too easy!

Convenience methods such as File.getText() and File.deleteDir() make scripting with Groovy easier and more convenient.

Groovy JDK (GDK): File.deleteDir()

One of the many things that I like about Groovy is its Groovy JDK (also known as GDK). As the Groovy JDK API Specification states, the Groovy JDK provides "methods added to the JDK to make it more groovy." The Groovy JDK is a collection of extensions to classes available in the standard Java SDK such as Object. As a collection of extensions to the standard Java JDK, the Groovy JDK is separate and distinct from the Groovy API, which consists of classes unique to Groovy. In this blog post, I focus on one highly useful method the Groovy JDK adds to the standard java.io.File class for deleting a directory.

The standard Java JDK provides a File.delete() method that will delete files or directories. The Javadoc documentation for this method explicitly states that this method will not delete a directory that is not empty (contains other directories or files). The same Javadoc documentation also states that the boolean returned by this method will be true if and only if the directory is actually deleted. In other words, if the directory is not deleted because it does not exist or because it contains files or other directories, a false will be returned.

The Groovy JDK (GDK) provides an extension to the standard File class. The GDK File extension adds a method deleteDir() that behaves differently on directory deletion than the just-described behavior of the standard File.delete() method. In particular, the GDK File.deleteDir() will delete a directory even if it contains other files and directories (it deletes those contents as well, of course). This is kind of like the rm -rf in Linux and is particularly useful when one is certain he or she really wants to delete the directory no matter its contents. This is often the case when writing scripts.

Besides obediently removing a directory regardless of it containing files and other directories, the GDK File.deleteDir() method is also different from the standard File.delete() when acting on directories because it returns true both in situations in which a directory is successfully deleted and in situations in which the specified directory does not exist. On the other hand, false is returned when the directory does exist and cannot be deleted or when the File being acted upon is not actually a directory.

The following Groovy code can be used to illustrate the differences between the standard SDK File.delete() and the GDK File.deleteDir().

directoryDelete.groovy

directory = new File("dirToBeDeleted")
printf "Delete directory $directory with JDK File.delete(): ${directory.delete()}%n"
printf "Delete directory $directory with GDK File.deleteDir(): ${directory.deleteDir()}"


The next screen snapshot shows the results of executing the above Groovy code snippet. The snapshot shows that the "dirToBeDeleted" directory does exist and that it does have three .txt files in it.



The first attempt to delete this directory with files using File.delete() fails and returns false. However, the second attempt with the GDK File.deleteDir() is successful.

The next screen snapshot shows how both the standard File.delete() returns true when called on to remove an empty directory. Even with the directory now removed, the GDK File.deleteDir() also returns true.



Finally, we can see an example of when the Groovy JDK File.deleteDir() returns false. To make this happen, I changed the permissions of the "dirToBeDeleted" directory to not allow reading or writing. When I run the Groovy script against that locked-down directory, I see the following results:



The Groovy JDK (GDK) File.deleteDir() method is a useful extension that can make for easier and more convenient scripting that involves deletion of directories. This is just one of many "extension" methods that the GDK provides as enhancements to the functionality provided by the standard JDK.

Tuesday, September 22, 2009

You Might Be a Programmer If...

You might be a programmer/software developer/software engineer if...

1) you are primarily offended by the use of goto when someone tells you to go to Hell.

2) you know that Perl is not Pearl misspelled.

3) you don't think gems when you hear "Ruby."

4) you think programming language/platform when you hear the word "Java."

5) you know what a noop is.

6) you are aware of many different kinds of beans that have nothing to do with plants (JavaBeans, Enterprise JavaBeans, Spring beans, MBeans, NetBeans, etc.).

7) you refer to rearranging furniture or rearranging/cleaning your desk as "refactoring."

8) you are more comfortable writing code than writing prose.

9) you think the real bugs have nothing to do with insects or spiders.

10) you know that 10-9.9 is not necessarily equal to 0.1.



Related Links

You Might Be A Programmer If... (GNU)

You might be a programmer if... (Clay Shannon)

You Might Be a Programmer if... (maxabout.com)

Saturday, September 19, 2009

Is a Java Immutable Class Always final?

In response to my recent blog posting Immutable Java Objects, Matt brought up a good point of discussion related to making Java classes truly immutable by declaring them as final so that they cannot be extended. His comment was:

"Implementation inheritance explicitly disallowed." -- isn't this largely orthogonal to the question of immutability?


In that previously referenced blog post, I listed several resources that explain how to write immutable Java classes. Each of these resources recommends making the Java class final as one of the steps in making it immutable. The resources with the recommendation include Brian Goetz's To Mutate or Not to Mutate?, the Java Tutorial section on A Strategy for Designing Immutable Objects, and Joshua Bloch's Effective Java.

A similar question to this is asked in the StackOverflow thread immutable class should be final?: "So why is immutability a good reason for making a class final?" In this blog post, I look a little more deeply into this issue.

The CERT Secure Coding Standards contains the entry OBJ38-J. Immutable classes must prohibit extension which succinctly describes a primary rationale for specifying an immutable Java class as final:

By declaring immutable classes final, we impose a guarantee that malicious subclasses capable of changing the state of the object and violating assumptions that clients often make regarding immutability, are not a concern.


In Immutable Objects in Java, the four authors (Haack, Poll, Schafer, and Schubert) include a section on "enforcing immutability." In this section they maintain that classes which extend immutable classes must also themselves be immutable. The authors suggest that making the immutable class final would be one way to deal with a situation in which "malicious code may try to subclass an immutable class" and "masquerade" as its parent type,

In Mutable and Immutable Objects, David O'Meara specifies that there are two approaches for ensuring methods are not overridden in a class designed to be immutable. He differentiates between strong immutability (class is made final) and weak immutability (methods are individually and explicitly declared final rather than declaring class final). In O'Meara's words, "The preferred way is to make the class final" (strong immutability).

With the above background details in mind, it's time to move on to some code examples.

The following Fraction class has some traits of immutability (such as its fields being final and private):

Fraction.java

package dustin.examples;

import java.math.BigDecimal;
import java.math.RoundingMode;

/**
* Example of almost immutable class.
*/
public class Fraction
{
/** Fraction's numerator. */
private final long numerator;

/** Fraction's denominator. */
private final long denominator;

/** Scale used in BigDecimal division. */
private final int scale;

/**
* Parameterized constructor accepting numerator and denominator for the
* fraction represented by me.
*
* @param newNumerator Numerator of fraction.
* @param newDenominator Denominator of fraction.
*/
public Fraction(final long newNumerator, final long newDenominator)
{
this.numerator = newNumerator;
this.denominator = newDenominator;
this.scale = 25;
}

/**
* Parameterized constructor accepting numerator and denominator for the
* fraction represented by me along with a scale for my decimal representation.
*
* @param newNumerator Numerator of fraction.
* @param newDenominator Denominator of fraction.
* @param newScale Scale of my decimal representation.
*/
public Fraction(final long newNumerator, final long newDenominator, final int newScale)
{
this.numerator = newNumerator;
this.denominator = newDenominator;
this.scale = newScale;
}

/**
* Provide this fraction's numerator.
*
* @return Numerator of this fraction.
*/
public long getNumerator()
{
return this.numerator;
}

/**
* Provide this fraction's denominator.
*
* @param Denominator of this fraction.
*/
public long getDenominator()
{
return this.denominator;
}

/**
* Provide double decimal representation of this fraction.
*
* @return Decimal (double) representation of this fraction.
*/
public double getDecimalRepresentation()
{
return (double) numerator / denominator;
}

/**
* Provide the BigDecimal representation of this fraction.
*
* @return BigDecimal representation of this fraction.
*/
public BigDecimal getBigDecimalRepresentation()
{
final BigDecimal bigNumerator = new BigDecimal(this.numerator);
final BigDecimal bigDenominator = new BigDecimal(this.denominator);
return bigNumerator.divide(bigDenominator, this.scale, RoundingMode.HALF_UP);
}

/**
* Provide String representation of this fraction.
*
* @return String representation of this fraction.
*/
public String getStringRepresentation()
{
return String.valueOf(this.numerator) + "/" + String.valueOf(this.denominator);
}

/**
* Provide String representation of this fraction.
*
* @return String representation of this fraction.
*/
@Override
public String toString()
{
return getStringRepresentation();
}

/**
* Main function testing this class.'
*
* @param arguments Command-line arguments; none expected.
*/
public static void main(final String[] arguments)
{
final Fraction fractionOne = new Fraction(2,3);
System.out.println("2 divided by 3 is " + fractionOne.getDecimalRepresentation());
System.out.println("2 divided by 3 is " + fractionOne.getBigDecimalRepresentation());
}
}


In the above example, neither the class nor its methods are declared as final. This allows a renegade subclass to be written as shown in the next class listing for RenegadeFraction.

RenegadeFraction.java

package dustin.examples;

import java.math.BigDecimal;

/**
* Class extending the 'immutable' Fraction class.
*/
public class RenegadeFraction extends Fraction
{
/**
* Parameterized constructor accepting numerator and denominator for the
* fraction represented by me.
*
* @param newNumerator Numerator of fraction.
* @param newDenominator Denominator of fraction.
*/
public RenegadeFraction(final int newNumerator, final int newDenominator)
{
super(newDenominator, newNumerator);
}

/**
* Provide double decimal representation of this fraction.
*
* @return Decimal (double) representation of this fraction.
*/
public double getDecimalRepresentation()
{
return 6.0;
}

/**
* Provide the BigDecimal representation of this fraction.
*
* @return BigDecimal representation of this fraction.
*/
public BigDecimal getBigDecimalRepresentation()
{
return new BigDecimal(5.0);
}

/**
* Provide String representation of me.
*
* @return My String representation.
*/
@Override
public String toString()
{
return
"Fraction with numerator " + getNumerator() + " and denominator "
+ getDenominator();
}
}


Because the parent Fraction class is not final and its method are not final, the RenegadeFraction class is able to override its methods and return nonsensical results. Note that even if we made the main methods final, the constructor of RenegadeFraction could still intentionally or accidentally swap the constructor arguments passed to its parent class.

This example also shows a misbehaving toString() implementation in the subclass. If we extend the Fraction class and mark the methods we don't want overridden with final, there could be confusing issues surrounding "other" methods like toString(). Do we want to make toString() final or allow the child class to potentially misrepresent its (and its parent's) real contents?

The next code listing demonstrates how a child class can misrepresent its parents to clients. The main code here believes it is dealing with Fraction class and may even make some assumptions based on that. The actual instance passed to the client is the RenegadeFraction resulting from intentional abuse or from careless development.

DemonstrationMain.java

package dustin.examples;

import java.math.BigDecimal;
import static java.lang.System.out;

/**
* Demonstrate how allowing an immutable class to be extended can reduce
* immutability, at least from the perspective of its behavior.
*/
public class DemonstrationMain
{
/**
* Enumeration representing type of fraction to help in readability of output.
*
* This differentiates between the original Fraction and the extending class
* RenegadeFraction.
*/
public enum FractionType
{
FRACTION("Fraction"),
RENEGADE_FRACTION("Renegade");

private String stringRepresentation;

FractionType(final String newStringRepresentation)
{
this.stringRepresentation = newStringRepresentation;
}

public String getStringRepresentation()
{
return this.stringRepresentation;
}
}

/**
* Accepts immutable Fraction object and prints its String value.
*
* @param fraction Fraction whose String value will be printed.
* @param type Type of fraction (for ease in reading output).
*/
public static void printFractionToString(final Fraction fraction, final FractionType type)
{
out.println("Fraction [" + type.getStringRepresentation() + "] is " + fraction);
}

/**
* Accepts immutable Fraction object and prints its String value.
*
* @param fraction Fraction whose String value will be printed.
* @param type Type of fraction (for ease in reading output).
*/
public static void printFractionStringRepresentation(
final Fraction fraction, final FractionType type)
{
out.println(
"Fraction [" + type.getStringRepresentation() + "] is "
+ fraction.getStringRepresentation());
}

/**
* Accepts immutable Fraction object and prints its decimal representation.
*
* @param fraction Fraction whose String value will be printed.
* @param type Type of fraction (for ease in reading output).
*/
public static void printFractionDecimalValue(final Fraction fraction, final FractionType type)
{
out.println(
"Fraction [" + type.getStringRepresentation() + "] decimal: "
+ fraction.getDecimalRepresentation());
}

/**
* Accepts immutable Fraction object and prints its BigDecimal representation.
*
* @param fraction Fraction whose String value will be printed.
* @param type Type of fraction (for ease in reading output).
*/
public static void printFractionBigDecimalValue(final Fraction fraction, final FractionType type)
{
out.println(
"Fraction [" + type.getStringRepresentation() + "] BigDecimal: "
+ fraction.getBigDecimalRepresentation());
}

/**
* Print quotient resulting from division of provided dividend by provided
* divisor.
*
* @param dividend Dividend in division.
* @param divisor Divisor in division.
*/
public static void printExternalDivisionResults(
final BigDecimal dividend, final BigDecimal divisor)
{
out.println(
"Division of dividend " + dividend + " by divisor " + divisor
+ " leads to quotient of " + dividend.divide(divisor));
}

/**
* Main function for executing immutable object or child of immutable object.
*
* @param arguments Command-line arguments; none expected;
*/
public static void main(final String[] arguments)
{
final Fraction fraction = new Fraction(2,3);
final RenegadeFraction renegadeFraction = new RenegadeFraction(2,3);

printFractionToString(fraction, FractionType.FRACTION);
printFractionToString(renegadeFraction, FractionType.RENEGADE_FRACTION);

printFractionStringRepresentation(fraction, FractionType.FRACTION);
printFractionStringRepresentation(renegadeFraction, FractionType.RENEGADE_FRACTION);

printFractionDecimalValue(fraction, FractionType.FRACTION);
printFractionDecimalValue(renegadeFraction, FractionType.RENEGADE_FRACTION);

printFractionBigDecimalValue(fraction, FractionType.FRACTION);
printFractionBigDecimalValue(fraction, FractionType.RENEGADE_FRACTION);

printExternalDivisionResults(
new RenegadeBigDecimal(fraction.getNumerator()),
new RenegadeBigDecimal(fraction.getDenominator()));
printExternalDivisionResults(
new RenegadeBigDecimal(renegadeFraction.getNumerator()),
new RenegadeBigDecimal(renegadeFraction.getDenominator()));
}
}


When the above demonstration class is executed, its output appears as shown below:



The output shown above demonstrates how a subclass can misrepresent its parent's advertised behavior. This can happen anytime implementation inheritance is involved, but it is more insidious when we have reason to believe the class involved is immutable. We could mark the methods as final to reduce much of this, but the constructor still has issues. Furthermore, marking all the parent class's methods as final rather than simply marking the entire class as final has some drawbacks. These include the potential conundrum about how to handle methods (such as toString()) that really should not be final and the risk of new methods being added to the parent class without the developer remembering or knowing to mark them as final.

In the DemonstrationMain class, I also made use of a custom class called RenegadeBigDecimal. The purpose of this class is to demonstrate the abuse of a subclass of BigDecimal. The code listing for RenegadeBigDecimal is shown next.

RenegadeBigDecimal.java

package dustin.examples;

import java.math.BigDecimal;

/**
* Demonstrating the troubles with non-final 'immutable' classes.
*/
public class RenegadeBigDecimal extends BigDecimal
{
/**
* Parameterized constructor accepting Long for instantiation of BigDecimal.
*
* @param val Long parameter intended, but not actually used, for
* instantiation of BigDecimal.
*/
public RenegadeBigDecimal(final Long val)
{
super(-1);
}

/**
* Example of intentionally abusing behavior likely expected for an
* immutable class by the subclass.
*
* @param divisor Divisor in division process.
*/
public BigDecimal divide(final BigDecimal divisor)
{
return this;
}
}


This last example shows how easy it is to abuse BigDecimal. Because the divide method was overridden to return itself, it is obvious that neither the BigDecimal class nor its method divide were designated as final. Even if the divide method would have been made final, the constructor could still have implemented bad intent and any client code thinking it was a BigDecimal would pay the consequences.


Trade-offs and Drawbacks of final Immutable Classes

There may be times when the ability to override a "largely immutable" or "mostly immutable" class is more important than having a "completely immutable" or "strongly immutable" class. Software design and development is full of trade-offs and this is just another one of those. The benefits of different degrees of mutability can be weighed against the costs. I believe it is no coincidence that Joshua Bloch changed the title of his Effective Java item on immutable objects from "Favor Immutability" in Edition 1 to "Minimize Mutability" in Edition 2. I think this is most readily done by starting with a class that is completely or strongly immutable and only relaxing its mutability in different ways when justified by the benefits of doing so.

Again, at least in my mind, it is no coincidence that the creators of the recently announced Noop project have stated that they wish to encourage immutability and that they wish to discourage implementation inheritance. I think in many of the cases in which implementation inheritance might be desired, it might be better to simply use composition to share common, immutable data and behaviors between two highly related, possibly immutable, classes. That advice doesn't sound particularly different than what many others have suggested before in terms of all classes, including mutable classes.


Conclusion

The safest way to make a class "strongly immutable" is to designate the entire class as final. Doing so ensures that no mistakes will be made in creating new methods in the future in the immutable class that are not marked final and can be carelessly or maliciously overridden. The final keyword applied at class level also prevents subclasses from "masquerading" as their immutable parent with very different behavior than that expected for the "immutable" parent class.



Additional References

Mutable and Immutable Objects

Making a Class Immutable

⇒ StackOverflow: immutable class should be final?

OBJ38-J: Immutable Classes Must Prohibit Extension

Bug 4617197 - RFE: Add Immutable types to Java

Immutable Objects in Java

Some Concurrency Tips (talks about benefits of immutable objects)

The Final Word on the final Keyword

Friday, September 18, 2009

Noop: Google's Language for the JVM

Perhaps the biggest news at the JVM Language Summit was the formal announcement of Google's Noop programming language for the Java Virtual Machine. Opinionated software and JVM languages are all the rage these days and Noop appears to be both. The main Noop project page states that "Noop's got an attitude" (another way to say it's opinionated) and the project's subtitle highlights its JVM nature and focus on testability: "A testable programming language running on the JVM."

I have find that I generally like opinionated software when its creators share the same opinions that I have and dislike opinionated software when its creators have strongly different opinions than I have. This is not a surprising observation, but it is a reminder that I should probably generally agree with the opinions that form a language's or framework's foundation and vision before jumping earnestly into that language or framework.

Noop's Opinions

As the project's subtitle ("A testable programming language running on the JVM.") suggests, testability is a primary objective in the design of the Noop language. Thus it is not surprising that many of the opinions behind Noop are related to language features that tend to make code testing easier. Major features that Noop is designed to strongly encourage include testability, dependency injection, readability, strong typing, and immutability. On the other side, Noop attempts to deter use of statics (often cited as problematic for testing), implementation inheritance, primitives, and boilerplate code.

Even the project's main page is highly opinionated. Take, for example, this description of dependency injection (I added the highlight):

Dependency Injection changed the way we write software. Spring overtook EJB's in thoughtful enterprises, and Guice and PicoContainer are an important part of many well-written applications today.


It is difficult to quantify the "thoughtful enterprises," though it is at least implied that those who use Enterprise JavaBeans (does this include EJB3/JEE5/JEE6?) are not as thoughtful.


Conclusion

We seem to be seeing more JVM-based languages coming out all the time. Most will probably never gain significant traction and be lost in the noise, but it will be interesting to see if Google-backed Noop can begin to compete with other JVM-based languages such as Groovy, JRuby, Jython, Scala, and other leading contenders for developer mind share.


Additional Resources

noop: A Testable Programming Language Running on the JVM

Google Urges Developers to Get in Loop with Noop

Google Launches 'Noop' Language for the Java Platform

Noop: A New JVM Language by Google

Google Delivers New Java-like Language: Noop

Google's Noop Steals the Show at the JVM Language Summit

Google Develops 'Noop' Language

Tuesday, September 15, 2009

Immutable Java Objects

Immutable objects are highly desirable. Because an immutable object's state cannot be changed, they are particularly useful in concurrent environments. Immutable options can simplify code and reduce chances of unanticipated and undesired state in objects.

I prefer that all of my Java classes provide for immutable objects unless there is a compelling need for them to be mutable. I'm not the only one who feels this way. In Effective Java (Item 15 ["Minimize Mutability"] in the Second Edition and Item 13 ["Favor Immutability"] in the First Edition), Joshua Bloch extols the virtues of immutable objects and emphasizes in bold text:

Classes should be immutable unless there's a very good reason to make them mutable.


Another proponent of immutable objects is Martin Odersky of Scala fame. He has stated about immutable objects:

we recommend that if you can make [objects] immutable, that's good, and you should try to find out where you can make objects immutable.


Conceptually, it sounds easy to create immutable objects. However, there are a couple nuances to note when ensuring that a Java class is defined so that its instantiated objects are immutable. Several resources outline the steps necessary to write a Java class that will lead to immutable Java objects. These resources include the previously mentioned Joshua Bloch Effective Java items on immutable objects. Other resources outlining the steps for making a Java object immutable include Java Practices, the Java Tutorials, JavaWorld's article Mutable or Immutable?, and developerWorks's To Mutate or Not to Mutate?.

Java classes that support immutable objects have the following characteristics:

• No "set" or mutator methods (object's state is set at instantiation/construction and cannot be changed later).

Implementation inheritance explicitly disallowed.

Fields are final and private.

• Its data members are either immutable or only provides access to defensive copies (also covered in Effective Java) of its mutable members.



As threading becomes more significant, immutable objects become more important. Trendy languages such as Scala and Clojure emphasize the importance of immutable data structures and immutable objects in their very design.

I have found that it works best for me to start with my objects as immutable objects and then only relax the immutability as absolutely necessary. This minimizes the mutability when it is required. In general, I resist the urge to "easily" use the IDE feature that quickly and thoughtlessly creates getter and setter methods for my new classes. I have found that it is better to think about how the class is used and only provide the mutability that is absolutely necessary.

Monday, September 14, 2009

Beware Software Management Overreaction

One of the most sinking feelings one can feel in software development occurs when a client or management overreacts to some crisis or mistake with onerous new requirements, procedures, and processes. In this blog post, I look at why those in authority sometimes do overreact, describe why overreaction can be dangerous and costly, and outline some ideas regarding how to reduce or prevent overreaction.

Why Do People Overreact in Software Management?

There are several explanations for why people overreact in management of software projects. Most of these are applicable to general overreaction in any area, but do apply specifically to software development.

Emotional

By definition, overreaction is associated with an emotional response that is inappropriate to the circumstances. Emotion can cloud over or completely obscure logic. Many poor decisions in life have been made in the heat of the moment when emotions run high and logic runs low. Emotions are usually high as a direct result of the incident being overreacted to. Often these incidents are most glaring when we can least afford them and stress levels are already high.

Helplessness / At Least Do Something

Another reason one might overreact is out of fear of not knowing how to resolve the situation in a reasonable fashion. If there is a problem with no clear solution, it may feel better temporarily to at least do something even if that "something" is not rationale or even a good idea. Sometimes the best thing to do is to do nothing, at least at first. Calmer heads are more likely to come up with more useful ideas for dealing with a particular issue.

Punishment

Overreaction may be directed at one individual, a team, or even the entire staff as a form of punishment. This is a little different than the previously covered reasons because it is more calculated and deliberate. However, that does not mean emotion is not involved; the desire to punish is often emotionally driven.

Send a Signal

Another calculated reason a person in authority might overreact is that he or she wishes to send a signal to other developers that certain (mis)behaviors are not tolerated. As with the punishment motivation, the person overreacting may be doing so intentionally to send a "stronger signal."

Lack of Understanding of True Cost of Overreaction

In some cases, a person in authority might feel their newly imposed procedure or process is perfectly reasonable because he or she does not understand the true cost and true negative consequences of it. This typically happens when a person with little or no hands-on software development experience attempts to decide on extreme measures related directly to some stage of producing software without consulting people in the know.


How Costly is Overreaction?

The total cost of overreaction is nearly impossible to quantify because it is so highly dependent on the situation and on the degree of overreaction. However, there are many different costs to overreacting and some of them are listed here. To illustrate many of these points, I will be using a simple example of an incident such as breaking the build.

Direct Cost can Exceed Original Incident Cost

Suppose that the build is broken occasionally because of developers in a rush. It is not a frequent event, but does happen from time to time. If the estimated lost developer time is, hypothetical speaking still, about 5 person-hours per week, it makes little sense to impose new procedures and policies that prevent that build breakage that require 50 developers to spend an extra 30 minutes per day checking out their code before merging. That's because 50 developers multipled by 0.5 hours per week means 25 person hours are spent to avoid a 10 person hour problem. That is an overreaction. The cure is worse than the disease.

There are cases where the extra time to avoid the problem may be justifiable. I am especially thinking of situations where one deems the quality benefits of the additional steps to be an advantage. However, if the new procedure is instituted solely to deal with the hours wasted on a broken build, it is nonsensical and counterproductive to institute additional procedures that will take more time than the thing being avoided.

For me personally, it is often better to have one longer work stoppage now and then as opposed to transitioning on a daily basis between the work I really need to accomplish and the mind-numbing steps added to avoid "incidents."

Unintended Consequences

Besides the direct costs of any new initiative instituted as part of an overreaction, there will almost certainly be unintended (and often negative) consequences. I have written before about the dangers of unintended consequences. These are especially challenging to quantify, but always seem to apply. A newly enacted procedure might be intended to reduce a certain undesirable event, but in the process leads to one or more different undesirable events. This can be especially true if the concept sprung from overreaction leads to cloaking bad incidents rather than actually preventing them.

Collateral Damage

One of the reasons that overreaction can be so disheartening to software developers is that we often know that the innocent are going to be treated in the same way as the guilty. Even worse, highly skilled and very experienced developers can sometimes be forced to endure the same restrictions applied to newer and less experienced developers after an incident occurs. In many aspects of like it is a laudable ideal to treat everyone the same, but it is a mistake in software development to treat the craftsman the same as the apprentice. Even worse, it is really despicable to treat the craftsman the same as the incompetent. Processes, procedures, plans, and initiatives spawned from overreaction often lump everyone together and deal with the least common denominator. There are many costs associated with this: lower productivity from the most productive developers, dissatisfaction in the people that are most difficult to replace, and lack of attention on the people who really need it.


How do We Prevent / Reduce Overreaction?

Count to Ten

Often the best way to avoid overreaction is to take the emotion out of it. If you're in the authority position or can influence the person with authority, try to wait at least a day (or preferably over a weekend) to allow emotions to cool and to reconsider the true cost of the incident you are tempted to overreact to.

Understand the Direct Costs of Your Reaction

Some of the worst consequences of overreaction I have seen are those that occur because the person making the decisions did not really understand the costs or consequences of their decisions. Before a decision is made like, "Before doing procedure A, one must always do procedure B," the person forcing that procedure on others should do them in a realistic environment to see how painful and costly they are and to truly determine there effectiveness.

Consider Unintended Consequences

One of the hallmark characteristics of many decisions made in haste and with emotion is that only one consequence is being considered. The decision usually does directly deal with that considered consequence, but it is important to consider the other consequences. As an extreme example, not allowing developers to write code will eliminate the addition of new bugs into the system. However, there are other consequences of this action such as no new code being written or maintained.

Apply Tweaks Rather than Seismic Shifts

One of the problems with overreaction is that it often leads to decisions that are not appropriate in terms of degree of seriousness of the original incident. It can often be better to reduce the first idea one has for dealing with a crisis to a smaller, less significant change and measuring if that is sufficient to meet the problem. Often, if cooler heads prevail, this is what happens anyway.

Acknowledge that Not Everyone is Equal in Experience and Skill

If developers have different grade levels or other indicators of their experience, then why not tailor processes differently for each grade level. If feasible, it would be even better to tailor to each individual. Much of the more successful open source community uses meritocracy in a similar fashion.

Contingency Plans

A big part of overreaction is often due to fear, shock, and a sense of hopelessness. This can be mitigated by considering some of the common things that can happen in software (hardware failures, defects, delays, difficult to maintain code, etc.) and have plans in place beforehand regarding how to handle them. This may help identify small steps that can be taken to reduce the likelihood of the problems in the first place and can provide calm and logic when the incidents do occur. Being proactive allows one to be less reactive.

Admit Mistakes

If a bad plan is put into the place as part of overreaction, the worst thing that can be done is to leave it in place to save face. It is better to admit that a response was overly reactive and either temper it or remove it altogether. This can be difficult to do even though it is the correct thing to do.


Conclusion

It can be very easy to fall into the trap of committing an overreaction to a significant event or incident. Unfortunately, this often exacerbates the problem and exasperates the development team. In this blog posting, I've looked at why we are prone to overreaction, some of the costs of overreaction, and some techniques to reduce the frequency and severity of overreaction.

Please feel free to add in the comments any reasons, costs, or remedies you have observed related to overreaction in software development.

Saturday, September 12, 2009

More Software Developers Should Write Blogs

With the pervasiveness of blogs focused on software development, it is sometimes easy to wonder if there are more bloggers than readers. There are so many software-related blogs that Jurgen Appelo recently started listing his Top 200 Blogs for Developers instead of the 100 he formerly listed.

The presence of so many blogs has helped me tremendously. There are three types of assistance these software development blogs have provided me.

1. Exposed to New Ideas, Concepts, Techniques, and Methodologies

Some blogs have provided me with information on a topic that I did not know much about. These are usually the blogs I run into when perusing DZone or similar sites.

2. Direct Answers

Some blog postings have helped me solve a particularly tricky problem by matching a search with Google or other search engine.

3. Links and References to Answers

A third category of assistance from software development blogs includes the blog posts that have not had the answer I sought directly, but have linked to or referenced material that did provide the answer. These can be especially helpful when I am searching on something and not quite using the appropriate term to have the search engines return the most popular related links.


Why Don't More Developers Write Blogs?

Even with all of these blog postings, I believe that we could all benefit from even more software developers writing blogs. The software development community would especially benefit in the second and third of the three categories of helpful blogs I mentioned above because more blogs would mean more potential sources of information for direct and indirect answers.

Some Many Most of the highest skilled and most experienced software developers that I know and work with personally do not write blogs. There are some obvious reasons for this such as lack of interest and lack of time (too busy with other projects, work, or other activities). However, I also know that at least part of the reason that some of these highly talented developers do not write blogs is that they underestimate the value of what they could contribute to the software development community. In the remainder of this blog post, I will look at why I think many of these developers who think they do not have anything to add are mistaken.


Software Development Blogs Present Lopsided View of Software Development

I have noticed a glaring difference between my perception of the software development world based on the blogs I see and the software development world that I experience firsthand through work, through discussions with attendees at software development conferences, and so forth. I think we as a software development community could benefit from more blogs from some of the "everyday developers" working in the trenches with many different languages, different operating systems, different project sizes, different problem domains, etc. We have all of these covered to some degree, but it feels like the blog coverage is tilted more to some areas than others.


Different Opinions and Perspectives Do Matter

Statements like "all opinions matter" can seem like politically correct lip service, but there is some truth to this, especially in terms of seeing both sides of the story when considering a new or different technology or language. In software development, we have a tendency to act like lemmings and follow trends and fads, sometimes without sufficient consideration of the negatives and costs associated with that fad. I have found that my best decisions are made when I combine my own experience and instincts with reading of well considered and articulated thoughts from proponents of all sides of an issue. I often see outstanding and thought-provoking feedback comments to a blog post and wonder why that commenter does not write his or her own blog post with that kind of insight.


It's All About the Little Things

I occassionally run into a particular problem with a particular language, library, or technology for which I am unable to find a solution via search engine. I have gotten so used to today's powerful search engines pointing me to a blog, forum thread, or article with the answer I am looking for that it is almost scary when there are no useful responses. This often happens when using very old technologies, very new technologies, or technologies without a large customer base. When a colleague knows how to resolve one of these problems, the first question I have to ask (to at least myself) is, "Why don't you blog about this?"


Nothing to Add

As I mentioned earlier, some of the blog posts that I have been very grateful for are those that did not directly answer my question, but which pointed me to the blog, article, or forum thread with the answer. In some cases, no particular source had what I was looking for, but the blog helped me arrive at the answer by triggering something in my mind or making me think about the problem in a different way. I think if more developers wrote blogs about the problems they have faced and how they have resolved them, our chances of finding these indirectly beneficial blogs would be greater.

Several years ago, I approached a respected colleague regarding assisting me with writing an article on software design. I respected his thinking process and was particularly impressed with his ability to think deeply regarding software design concepts and techniques. He had never written a technical article or blog post, but I felt that he would be a great asset in writing a highly useful article on software design. He was very interested in the proposed project, but felt inadequate from the very beginning. He wondered what he could add on top of what was already out there in terms of software development. As we had our initial discussions about the outline of the article and what we'd write, I became increasingly excited about the article's potential. Unfortunately, we ended up not writing that article as we got distracted by other things and I have always felt that at least part of the reason we never wrote that article is the overwhelming feeling of having nothing to add. To me, that's the community's loss because I really thought that some of the ideas he and I came up with together were just enough different in perspective from what was already available to add real value for readers.


Strong on Concept; Weak on Experience

My feeling is that the software development community has greater coverage in terms of software development theory and concepts in our blogs than we do in terms of practical, hard-earned experience and details. Some of my favorite blog postings have been those which have relayed a real-life, practical experience and the lesson learned from that experience. It is one thing to say, "You should always do it this way," but it is entirely more useful and convincing to explain in practical terms why you should do it that way. These posts can be difficult to write because they acknowledge mistakes and weaknesses, but they can be highly beneficial for others. After all, one can learn much from one's own mistakes, but it is even better (and less costly) to learn from the mistakes of others. Some examples of blog posts that fit into this category include Rotten Statics (related to Inconstant Constants in Java), Don't Ignore serialVersionUID, and The * Stupidest Things I Have Done in My Programming Job.

It is important to note here that some of the most popular blogs that are strong in theory and concept are so strong because the writer does have deep and broad practical experience behind the theory and concept. Still, in terms of convincing one of the value of the theory or concept and in terms of understanding the significance of theory or concept, it is difficult to be more effective than by telling a sad story based on real events. If more bloggers were willing to share their failures and disappointments, there would be more evidence to back up the conceptual blog postings.


Nobody Would Read It Anyway

Some highly skilled developers do not blog because they believe no one will read their words anyway. Admittedly, they are correct in this assumption, at least early on. It usually takes time to gain regular readers and there is no guarantee that one will ever gain any significant number of regular readers. If that is the only reason one wishes to blog, then it might not be worth the effort. However, even if a blog is only read by people searching for something and running into a blog post via search engine, the community will benefit from the existence of the blog post. For the early months of my own blog's existence, the vast majority of viewers of my blog came to it through search engines. That has gradually shifted to the vast majority coming to it from links, due at least in part to the syndication of my blog on JavaWorld.

I started my blog with the thought that even if no one else ever read it, it would at least serve as a glorified bookmark of principles, concepts, techniques, and ideas worth remembering. I have actually used it several times this way to quickly find something that I knew I had written about but could not quite recall the exact details about.


Selfish Motivations

Besides serving as a "glorified bookmark," a blog can be beneficial for other selfish reasons as well. It can serve as evidence to potential and current clients and employers of one's experience and familiarity with particular techniques. It can be a soapbox for one's opinions. If the folks you work with are tired of hearing your rants, consider a blog as another outlet. In fact, a blog can provide a way to let off a little steam about things that are bothering you. The act of writing a blog can even help one organize and articulate one's own thoughts better. The fact is that even these selfish motivations can lead to blogs that might challenge readers and improve the software development community discussion.


Online Tools Are Equalizers

I think the software development community would benefit tremendously from more blogs by a wider demographic of software developers. It's not that I have time to read any more blogs: I cannot even read all that I'd like to read as it is. However, there are many tools at our disposal that would help us benefit from more blogs from a wider set of personalities and experiences. First, sites like DZone help choose some of the most interesting articles. Even a first-time blog writer could post his or her blog posting to DZone and, if it was particularly good, could get some immediate attention. Second, the powerful search engines make nearly any blog post a potential hit. If we had more blog posts from a wider group, we'd be more likely to see their posts show up in niche searches. Because the search engines and social tools like DZone favor blogs with characteristics that typically imply a certain level of interest, new blogs that truly have nothing to add are largely ignored. This is important because it does reduce the noise.


Conclusion

There are many times when the herd of software developers start moving toward the siren's song and it would benefit all of us if we had a few more people trying to snap us out of their trance or at least slow us down enough to reconsider the real benefits and costs. Besides adding to the discussions regarding software development, more sharing of practical, real-life experience could help each other reduce loss, minimize bad decisions, and improve productivity.