Software Development
Archived Posts from this Category
Archived Posts from this Category

Albert Einstein once mused:
“Reality is merely an illusion, albeit a very persistent one.”
Unfortunately for the vast majority of commercial players in the Java tools market, he may be incorrect– reality isn’t an illusion. It’s a harsh (and rather persistent) truth. You need only scan the various development tools you use on a daily basis to see that free, for the most part, is king these days.
Two recent SDTimes articles do a great job of highlighting this reality: first, Andrew Binstock wrote an article dubbed “Java tool market disintegrating” in which he states that the market for selling tools to Java developers
has been unhealthy for years. It is hard to think of a single Java-only tools company that has grown and prospered. One exception is KLGroup, which later became Sitraka and sold for a small fortune to Quest Software during the Internet bubble. Beyond it, though, things drop off quickly. Small companies struggle, living out their bets on Java.
He goes on to highlight three recent events such as Agitar’s demise, Enerjy’s freebee spree and lastly, CodeGear’s mercy acquisition (one can argue Embarcadero received an 85% discount on the purported $150 million value of CodeGear). Each of the aforementioned affairs do suggest the market for selling tools to Java developers (keep in mind that the CodeGear acquisition included non-Java tools and the support revenue associated with them i.e. Delphi) is rather limited.
Second, SDTimes was quick to release the news that McCabe Software is acquiring Agitar’s assets. On the surface, that could be good news, except for the fact that a Gartner analyst is purported to have said that Agitar’s product
might be a good fit within larger suite or a family of QA technologies.
Because it’s my bag, using the word might in the same story regarding an acquisition is not exactly positive. It’s like having the word disappointing show up on your resume or during a reference check, man. What’s more, no dollar figure was highlighted in the article nor the official press release, suggesting Agitar’s IP was picked up for peanuts (do you think McCabe received an 85% discount like Embarcadero? $5 million? It’s hard to believe they would pay even that much).
It remains to be seen if McCabe can attain a reasonable market share with the purchased assets; suffice to say, history (and don’t forget reality, baby!) are working against them.
That’s not to say that all commercial tools are doomed– in fact, you need only go to a Java oriented conference to see that IntelliJ continues to impress legions of smart people, who do pay for the copasetic tool even in the face of free competition from the likes of Eclipse. Plus, Atlassian continues to wow developers across the globe (they sell various products, however, like JIRA, which isn’t necessarily a tool marketed to and used by Java developers alone).
It seems a more apt mechanism for describing reality for the majority of commercial tool players in the Java market is, as Jane Wagner eloquently stated,
“Reality is the leading cause of stress amongst those in touch with it.”
Indeed, as Andrew Binstock pointed out in his article and as Atlassian is currently demonstrating, the actuality of the Java tools market is that those companies that wish to prosper selling tools to developers must offer a cornucopia of products to a wide range of audiences. That is, they must sell tools not only to developers but to other stakeholders in the application life cycle– and even then, success (i.e. healthy revenues) is no guarantee. Plus, in this Age of Aquarius, it helps if the company is bootstrapped and thus isn’t required to provide exponential returns in a short timeframe. Can you dig it?
5 comments Wednesday 16 Jul 2008 | Andy | Software Development
REST is a style of designing loosely coupled Web applications that rely on named resources rather than messages. Ingeniously, REST piggybacks on the already validated (and successful, don’t you think, man?) infrastructure of the Web– HTTP. That is, REST leverages aspects of the HTTP protocol such as GET and POST requests. Because it’s REST’s bag, RESTful applications turn out to be quite clean in their API as you don’t spend a lot of time reinventing the wheel– you get a lot for free when leveraging HTTP.
I’ve been keeping my eye on JSR 311 as it seemed to make a lot of sense to leverage attributes given the template-like pattern employed by the Restlet framework. For instance, without attributes (and by correlation, JSR 311, which is supported by a developmental version of the Restlet framework), you are forced to override specific methods in the base framework’s hip Resource class associated with HTTP verbs– public void post(Representation representation) handles HTTP POSTs; what’s more, given that the framework doesn’t actually know if a subclass has implemented a particular method, you must also override the allowPost method in the case of POST.
In fact, leveraging attributes in the case of JSR 311 (or, as previously mentioned, the 1.1 snapshot version of the Restlet framework) is a lot like comparing JUnit 3.8.1 to JUnit 4– the entire framework paradigm is shifted, which has the result of a lot less noise (a.k.a code).
For instance, implementing a GET request via JSR 311 is as easy as leveraging the GET attribute:
@GET
@ProduceMime("text/xml")
public String get() {
Collection<Race> races = Race.findAll();
return this.reporter.racesToXml(races);
}
Note, this code is leveraging Jersey, Sun’s reference implementation of JSR 311 (which recently released version 0.8). What’s more, JSR 311 specifies mime annotations for both requests and responses — for instance, the get method above responds with a mime type of “text/xml” — you can easily specify JSON, etc too.
Handling other requests, such as a POST request is just as easy– just use the corresponding copasetic annotation (for instance @POST). Note too, with mime types, you can specify accepted request types. In the case below, the post method will only accept “text/xml”.
@POST
@ConsumeMime("text/xml")
public Response post(String xml) throws Exception {
long id = this.consumer.createRace(xml);
return Response.created(uriInfo.getBaseUriBuilder().
path(Long.toString(id)).build()).build();
}
Of course, the two method above are related to a particular path or URI– JSR 311 supports the @Path annotation, which interestingly enough, is inheritable such that a method can expand upon a base path specified at the class level. For instance, the method above live in class defined as follows:
@Path("/race")
public class RacesResource {
//...
}
Thus, all exposed RESTful methods will respond to the /race URI (i.e. a HTTP GET to /race will be handled by the get method and a HTTP POST to the /race URI will be handled by the post method (provided the request be of mime type “text/xml”, don’t forget!)). Methods can expand upon the /race URI by providing their own @Path annotation, which will effectively append the specified URI to the base URI.
There are certainly more than a few ways to skin the REST cat in Java, baby– you’ve got, to name a few, Restlets, Grails, 1060 NetKernel, and now JSR 311 via Sun’s Jersey. Each framework comes with its own bells and whistles; nevertheless, JSR 311 and Jersey definitely lower the barrier for building (and deploying) RESTful applications even if they are fairly late to the party.
4 comments Wednesday 16 Jul 2008 | Andy | Software Development
Dan North, the veritable progenitor of behavior driven development (or BDD), recently blogged about unnecessary DRYness (meaning don’t repeat yourself) with respect to clarity of intent when it comes to testing (in generic terms of the word). Essentially, in the case of a JUnit test, for example, by utilizing a setUp method and possibly other helper methods, the test itself becomes somewhat cluttered– one must jump around the code to truly understand the intention of the test in the first place. 
In fact, Dan says it quite nicely– tests (or stories, baby) are:
“examples [that] tell a story about what the code does… [and] clarity of intent is found in the quality of the narrative, not necessarily in minimising duplication.”
Thus, over utilizing the DRY principle can be ineffective when it comes to testing; indeed, he makes a great point! If tests or stories are intended to serve as “executable documention” doesn’t it make sense to make them as easy to read and understand as possible?
As such, because it’s my bag, I took the liberty of pondering the depth of favored term DRY and decided that when it comes to clearly expressing intent with respect to stories (as in the case of easyb) or tests, it often pays to be WET– that is, wholly express your tactics, baby.
You see, applying WET to, say, an easyb story then yields perhaps more text, but it leaves no room for misinterpretation, man. For example, imagine a story regarding discounts (this is my touchstone example that is in danger of itself becoming dry– no pun intended either, man). The high level story is such that VIP customers receive varying discounts depending on the amount of money a particular order has– you could even require a minimum number of items too (if you were attempting to move inventory). Thus, one scenario could be:
scenario "VIP customer with 3 items, over $30 receiving 10% discount", {
given "a VIP customer"
and "given they have at least 3 items totaling over $30"
when "they proceed to checkout"
then "they should receive a 10% discount"
}
Of course, from here, stakeholders, through a collaborative effort, realize more scenarios are possible– for instance, the VIP customer has 3 items totaling over $100– thus, a higher discount is applied. A first stab of staying WET (that is, wholly expressing your tactics, man) yields this scenario:
scenario "VIP customer with 3 items, over $100 receiving 15% discount", {
given "a VIP customer"
and "given they have at least 3 items totaling over $100"
when "they proceed to checkout"
then "they should receive a 15% discount"
}
Reading these scenarios (which are executable, by the way!) leaves no room for missing the boat– the tactics involved are wholly expressed!!– reading them is somewhat effortless from the standpoint that you don’t necessarily need to jump around the file to gain a clear understanding of context.
If you prefer staying DRY, the story can become more concise–
before_each "a VIP customer with 3 items is assumed", {
given "a VIP customer"
and "given they have at least 3 items"
}
scenario "VIP customer with 3 items, over $30 receiving 10% discount", {
given "the 3 items total at least $30"
when "they proceed to checkout"
then "they should receive a 10% discount"
}
scenario "VIP customer with 3 items, over $100 receiving 15% discount", {
given "the 3 items total at least $100"
when "they proceed to checkout"
then "they should receive a 15% discount"
}
Both stories convey intent– it is just that the WET one is more clearly expressed– in the DRY example, as more and more scenarios are added (and they surely will), one needs to jump to the top to gain an understanding of the underlying assumption (that is, a VIP customer with 3 items in their shopping cart).
DRY is fundamentally a sound principle– I’m not here to deny that; however, like all good things, it can be overused without regard for a particular situation. In fact, Johann Wolfgang von Goethe (of Faust fame, baby) is quoted thus:
“The phrases that men hear or repeat continually, end by becoming convictions and ossify the organs of intelligence.”
Because it is everyone’s bag, baby, think through DRYness from time to time and realize that in some cases, it is perfectly acceptable to WET yourself (I mean, to practice WET). Can you dig it, man?
8 comments Wednesday 02 Jul 2008 | Andy | Developer Testing, Software Development
It’s clear that the initial bogue bet on Java’s ubiquity in the browser, in the form of applets, never paid off– history, however, has shown that Java found its foothold on the server-side. Nevertheless, because it’s everyone’s bag, applets are still around as I run into them from time to time. Interestingly, Sun has been putting some effort into underlying engine that runs applets (the Java plug-in), which begs the question– are applets still alive? What’s more, if they aren’t (or are on life support as some have suggested), what happened to them?
Richard Monson-Haefel recently pointed me to an hip conversation with everyone’s favorite disco superstar, Ted Neward (who you may have heard blather on and on (and on!) about Scala recently) who yammers (on and on and on– in reality, only 15 minutes but they do cut him off as he’s chattering on and on and on!) about why he thinks applets effectively kicked the bucket.
Just the same, Sun hasn’t thrown in the towel! In fact, not long ago, I had the privilege of conducting a dialog with Ken Russell, a Sun engineer focused on rebuilding the Java plug-in. According to Ken, applets aren’t dead yet and are a compelling platform for building Rich Internet Applications.
Both conversations are appealing in that they shed some light on the lessons learned about Sun’s initial applet bet and where the future may be headed (regardless if applets will be with us or not). For me, I’m not sure applets are dead just yet– Ken gave me reason to believe otherwise. Have a listen to both Ted Neward and Ken Russell and decide for yourself, man!
3 comments Wednesday 25 Jun 2008 | Andy | Software Development
I recently had the opportunity to discuss Scala with my friend Ted Neward for JavaWorld’s Java Technology Insider. Ted’s been talking about Scala for quite some time now and he’s the person who turned me on to this compelling functional language.
In this conversation, Ted explains what functional programming is and why people should care– he’s got some interesting thoughts regarding OO languages versus functional languages and more importantly, where each paradigm is a good fit. Scala’s definitely got some interesting features– if you are curious to hear them, then have a listen, man!
1 comment Friday 20 Jun 2008 | Andy | Software Development
Back in the Age of Aquarius, a popular pattern emerged in the Java world dubbed “the data access object“, which essentially
“separates a data resource’s [hip] client interface from its data access mechanisms”
meaning that clients to a particular domain object were shielded from the actual implementation of communicating with a particular database. Provided that clients worked with the interface type, implementations could be switched out (the database could migrate from DB2 to Oracle, for instance or one DAO type could leverage Hibernate, another IBATIS). This pattern had the bogue consequence, though, of logically dividing up a data layer into two types– DAOs and individual domain objects.

For instance, if you had a copasetic Customer domain object, you would also have a CustomerDAO interface type– your Customer object would essentially be a struct and the DAO type would handle CRUD (create, read, update, delete) operations. If you needed to find a particular customer, you’d ask the DAO type, for example, invoking the findCustomer(long id) method on the CustomerDAO object, which would return a fully populated Customer object.
This pattern seemed well and good at the time– I admit to using it extensively on a large project ages ago (after disco though); however, after a while it seemed to be a lot of work– if, because it was my bag, I wanted a Customer object, why did I have to ask the CustomerDAO for it? Why couldn’t I just ask the Customer itself? On top of that, if I wanted to create a new Customer, I had to first populate a Customer object and then pass it to the DAO type and invoke the create method.
I’m sure at the time a lot of smart people eschewed this uptight pattern and designed more natural domain objects; but for me, the tides changed when I read an interesting article about Naked Objects and then looked deeply at Rails (and subsequently, Grails) as they came to mature– these frameworks have no notion of a DAO type– your domain object (Customer) does everything for you– you can create new Customers, save instances, find instance, etc.
I recently found myself building a domain model in Java without the luxury of Grails or GORM; however, I did employ Hibernate and Spring. My initial effort starting going down the traditional DAO-domain object pairing but I quickly found myself disgusted– as a result I started playing around with combining the duo into something as hip (and polished) as what Grails/Rails would give you. My goal, of course, to provide a domain object that handled everything rather than having clients of the domain object have to work with two different trippin’ objects.
In the end, I still have two different objects and an interface type to link them (via Spring); however, clients need only work with one hip type– the domain object. My domain objects support instance methods like create, remove, and update and class methods for find-like methods.
I nonetheless still have a DAO object– it’s essentially a Spring wired HibernateTemplate– this object supports the true CRUD logic and is directly bound to Hibernate. For example, given a Race domain object, the DAO looks like this (minus some instance and class methods, but you’ll get the point):
class RaceDAOImpl implements RaceDAO {
private SessionFactory sessionFactory;
public RaceDAOImpl() {
super();
}
public void setSessionFactory(final SessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
}
public void create(final Race race) {
final HibernateTemplate tmplte =
new HibernateTemplate(this.sessionFactory);
tmplte.save(race);
}
//...
public Race findByName(final String name) {
final HibernateTemplate hibernateTemplate = new HibernateTemplate(this.sessionFactory);
return (Race) hibernateTemplate.execute(new HibernateCallback() {
public Object doInHibernate(Session session) throws HibernateException {
return session.createQuery(
"from ... name = ?")
.setString(0, name.trim())
.uniqueResult();
}
});
}
//...
}
Note that this class isn’t public– it isn’t intended for outside consumption– the only client to this class (which will be shown shortly) is the domain object (which lives in the same package).
With this DAO object, I extracted an interface type– RaceDAO. This interface is the link between the domain object (Race) and the DAO (that is, the domain object will work with the interface type not the implementation or because it’s everyone’s bag to describe things in terms of coupling– the domain object is loosely coupled to the DAO implementation).
interface RaceDAO {
Collection<Race> findAll();
Race findById(long id);
Race findByName(String name);
//...other finders...
void create(Race race);
void update(Race race);
void remove(Race race);
}
The domain object (which clients rely on) then relies on Spring (which basically acts as a factory) and composition to expose instance and class methods that indirectly (i.e. delegate via composition) leverage Hibernate to manipulate persistence.
For instance, the Race domain object looks like a normal, hip domain object– it contains various properties (and consequentially getters and setters) related to races (races have runners and results, etc) like so:
public class Race {
private long id;
private String name;
private Date date;
private double distance;
private Set<Runner> participants;
private Set<Result> results;
private String description;
//.....more to come
}
The next step could have unfolded in a number of different ways; however, I kept on truckin’ and ended up with something that works– there are certainly pros and cons associated with my choices though (I will point those out shortly).
The DAO interface is linked via Spring in a static block in the domain object like so:
private final static RaceDAO dao;
static {
ApplicationContext context =
new ClassPathXmlApplicationContext("spring-config.xml");
dao = (RaceDAO) context.getBean("race_dao");
}
Note that the type in the domain object is the interface (RaceDAO) not the implementation — Spring is returning some type that is bound to the String race_dao, which in my case is the Hibernate template type shown earlier.
Thus, because the RaceDAO is a static type, I can then expose a series of class methods on the domain object for finding particular race instances like so:
public static Collection<Race> findAll(){
return dao.findAll();
}
public static Race findById(long id) {
return dao.findById(id);
}
//...others...
Plus, instance methods on the domain object also delegate to the interface type:
public void create() {
dao.create(this);
}
Now clients of a particular domain object don’t need to handle or work with various copasetic objects– they work exclusively with a domain object (much like you would in Grails, for instance). For example, the following easyb scenario demonstrates the behavior of a Race instance:
scenario "Race should support finding races by name", {
when "the find by name method is called", {
race = Race.findByName("Leesburg Marathon")
}
then "the race should have 100 runners", {
race.participants.size().shouldBe 100
}
}
As you see in the Groovy code above, the findByName method is a class method– it returns a Race instance, which clients can then work with.
Instance methods on the domain object work too, for example, creating a new race instance and persisting it is as easy as invoking the create method:
scenario "the domain object should faciliate creating new instances", {
given "a new race is created", {
new Race("SML 10K", new Date(), 6.2,
"race the hills of Smith Mountain lake").create()
}
then "the domain class should actually find it by name", {
race = Race.findByName("SML 10K")
race.description.shouldBe "race the hills of Smith Mountain lake"
}
}
As I mentioned earlier, there are some bogue disadvantages to this strategy– that is, because it’s its bag, the static block forces clients to load some instance of the DAO– without mocking that instance out, the domain object becomes somewhat heavy. For instance, loading the Race class with a Hibernate wired DAO means that a database must be up and running. Thus, without some mocking of the DAO interface type (and subsequent wiring of Spring) these domain objects can be hard to truly unit test.
The advantage of this strategy is that clients don’t have to deal with a DAO type– they have a more neat-o-natural interface to work with– that being the business object itself (i.e. Customer or Race or Runner, etc). There are still two objects (and a binding type) to work with; however, the DAO is hidden. And in keeping with the spirit of the original DAO pattern, implementers are free to create varying instances of the DAO (should they actually need more than one– unit testing certainly comes to mind for a need to create at least one other instance).
The data models offered by frameworks like Grails and Rails are pretty hippingly sophisticated as well as elegant; what’s more they are easy to learn and natural to use. At this point, however, GORM (Grails magic data layer sauce) isn’t available as a stand alone project for Java developers; consequently, hip developers are left to rolling their own models (which leverage Hibernate, JDBC, IBATIS, etc), modeled after said project’s elegance.
The DAO pattern as it was authored (and implemented) back in the day is heavy, man; however, by applying a bit of Spring (or some other IOC framework) and leveraging a restrictive class modifier (to thus hide objects from clients), you can create more natural domain objects that still live up to the promised flexibility of the DAO pattern. Can you dig it, baby?
18 comments Tuesday 17 Jun 2008 | Andy | Groovy, Software Development
My friend, John Ferguson Smart, recently authored Oreilly’s Java Power Tools, which Andrew Binstock has said is “a must-have reference for the bookshelf” of Java developers. I couldn’t agree more with Andrew and am still amazed John was able to amass so much valuable information into a veritable bible for software development.
I had the pleasure of chatting with John for JavaWorld’s Java Technology Insider before the book was published and we had a lot of fun discussing Maven 2, JUnit, Hudson, and a host of other tools. John’s got a great deal of knowledge regarding these and other tools– all you have to do is see that the book is 900+ pages to figure that out!
Have a listen to “John Ferguson Smart on Java Power Tools” and don’t forget to pick up a copy of his book– it’s a vade mecum for anyone serious about producing working software effectively.
2 comments Monday 16 Jun 2008 | Andy | Software Development
Towards the end of 2007, I had the hip privilege of chewing the fat with Andrew Binstock for JavaWorld’s Java Technology Insider regarding the Java IDE market, which, as anyone who hasn’t been living in cave (and listening to disco) for the last 10 years knows, has gone through some substantial changes since Java’s inception.
Andrew has some copasetic thoughts to share regarding Eclipse, NetBeans, and everyone’s favorite, for pay no less, IDE: IntelliJ; plus, Andrew muses about RAD, JBuilder, and Oracle’s JDeveloper. I am a recent convert to IntelliJ, and the conversation was rather influential in convincing me of giving IntelliJ a try.
Have a listen to “Andrew Binstock rounds up the Java IDEs” and see if you agree with him, man.
2 comments Sunday 15 Jun 2008 | Andy | Software Development
My friend Venkat Subramaniam, who played a role in shaping early versions of easyb’s hip DSL, has recently published an article dubbed “Creating DSLs in Java, Part 1: What is a domain-specific language?” on JavaWorld. This is an excellent article that demystifies DSLs and demonstrates that you probably use them daily.
One of my favorite points Venkat makes is:
Simplicity is critical to the success of a DSL. A person familiar with the language’s domain must easily understand it.
He goes on to add:
Creating a good DSL is like cooking a nutritious meal; just like you want kids to eat vegetables without realizing and fussing over them, you want clients to use your DSL without worrying about its syntax.
Because it’s their bag, this notion of simplicity has been a guiding principle for the easyb team; yet, striving for clarity, conciseness, and expressiveness (other points Venkat goes on to make) within a DSL is harder than you think! You only need look at a classic make file to see, in my opinion, a DSL that creates a lot of fuss, baby.
Check out Venkat’s copasetic article and while you are at it, don’t forget to check out easyb, man!
0 comments Saturday 14 Jun 2008 | Andy | Dynamic Languages, Groovy, Software Development

Ralph Waldo Emerson is often attributed to copasetically saying (or most likely writing) something like:
“build a better mousetrap and the world will make a beaten path to your door”
This Sirens call has lured many an individual to build a superiorly hip mousetrap. Yet, the truth of the matter is that the world has warehouses full of better mousetraps; unfortunately, the traps are gathering dust at the expense of the inventors (and perhaps distressed investors).
The basic mouse trap works, man. It is low cost and simple to use– put some cheese on it, place it in a strategic location where mice are known to be and bingo! soon enough you’ll have yourself a mouse (dead or alive). It’s not pretty, nor is it entirely effective when it comes to scalability; however, it’s hard to overlook the fact that a mouse trap runs you about $1 (plus the cost of a morsel of cheese).
Better mousetraps, while technically superior, are often more complicated and in many cases, because it’s their bag, more expensive. Some people will buy them and find them useful; however, the average disco dancer (otherwise known as “Joe”) doesn’t care so much about the fancy trap– he or she wants mice exterminated quickly. Accordingly, they still buy the basic mouse trap because they know how it works and it costs about a dollar. And in the end, it does basically the same thing as the snazzy “better mousetrap”– that is, removes mice, baby!
Better mousetraps will always be around so long as the cost to produce them is less than what is earned by selling them (the higher the difference has a direct relationship to how long that mousetrap will last on the market too– people like making money almost as much as they love disco music). People, from time to time, will buy the superior mousetrap– often times because they’ve done the research and realize they have a particularly bad mouse problem. This realization, though, takes a lot of self discipline and honesty that the average Joe lacks. Also too, it costs a lot of money to educate the market about the superior mousetrap– most hip people don’t care because they understand the essential premise of the basic mousetrap!
In essence, xUnit (and related frameworks) are the basic mousetrap. In fact, developer testing (in the form of JUnit or any xUnit framework) is free. You can download frameworks like JUnit and start coding with them in less than a minute– maybe 10 minutes if you decide to read some documentation.
They work (they catch mice)! They are effective, but maybe not entirely pretty. Scaling xUnit across a wide code base with no testing is, at best, a herculean effort. It is challenging to overlook, though, the basic cost– $0. People who download these frameworks are motivated by pain– in this case, defects, and they are looking for a solution (often times, though, they are looking for an easy solution to a difficult problem– i.e. lots of mice procreating at a rapid pace– but knowing that they have a deep problem takes a lot of honesty and discipline, remember?).

Companies have, indeed, baby, built better mousetraps for testing. For instance, Agitar’s product was phenomenal (and their team, outstanding); nevertheless, their superior mousetrap cost a heck of a lot of money. In the end, however, the Agitator produced JUnit tests. The same tests that one could have arguably written for free (yes, I know that in reality many of tests would have never been written by hand, however).
In essence, Agitar took a commodity (a mousetrap, but in this case, JUnit) and made it better– indeed, they have (or is it had now?) a good customer base (meaning they actually had customers, man). There were people that saw the benefit and had the discipline and honesty to admit they had a problem that the Agitar could solve in a superior manner.
Don’t forget basic economics though– the cost to produce their mousetrap was significant. There are only so many people who would buy a $500 mousetrap when sitting right next to it, on the same shelf, is the dollar variety (which, by they way, works fine). So too, there are only a few companies that would likely spend roughly $50,000 to $100,000 on a tool where any Google search would display a link for another tool that has zero cost (i.e. junit.org).
Indeed, there are other smokin’ companies selling superior unit testing tools that are still operating today; however, if you look closely at the big names, they have a diversified portfolio of products and it wouldn’t surprise me if their economics work out more favorably (but keep in mind the statement regarding profit and cost and the difference of the two related to length of presence in a market).
When it comes to better mousetraps, there is another well-aimed saying, which is, nonetheless, only partially true:
“Before you build a better mousetrap, it helps to know if there are any mice out there”
Indeed, this quote is half correct, for as everyone in this Age of Aquarius knows, taking the same hip comparison of mousetraps to testing tools and mice to defects, there are plenty of defects out there! The essential aspect this quote fails to mention is that:
“and you had better make sure there are plenty of well educated, motivated customers who will actually pay real money for the mousetrap (even though they could buy something similar on the cheap), baby!”
The business model (or lack thereof) of selling unit testing tools is difficult. Period. If you want to do it, you had better make sure you can build the better mousetrap on the cheap and that there are a lot of people who are educated, disciplined, and honest enough to pay for it.
I have mice (actually defects, but you get the point, man) and have, from time to time, considered buying the superior mousetrap; however, more often than not, I’ve ended up purchasing the dollar variety because it is quick and easy. Unit testing isn’t dead, baby– the inventors of better mousetraps (that have failed) often tout that mice will overrun the world. No, unit testing is a largely established practice that will gradually grow because the cost is free. Mice will always be around and people will always want to exterminate them– they just don’t always want to pay through the nose to do it, man. Can you dig it?
6 comments Thursday 29 May 2008 | Andy | Developer Testing, Software Development