Sunday, November 22, 2009

Array of Generic Type

I was asked why one cannot create an array of generic type, which means this line cannot compile:


// the below doesn't compile
ArrayList<Integer>[] arrayOfLists = new ArrayList<Integer>[7];


The compiler doesn't like the creation part, on the right, while the declaration alone, on the left, goes fine. This issue is widly discussed, e.g. nicely described here.

There are many ideas why it is forbidden and many suggestions for workarounds. But the nice colleague who asked me this question liked the most the workaround I suggested him, which is very simple.

I started by asking why he needs this.

And he explained that he needs to manage some info for 7 days a week:


// the below doesn't compile
ArrayList<SomeInfo>[] weeklyInfo = new ArrayList<SomeInfo>[7];


I suggested to create two new classes, DailyInfo and WeeklyInfo:


class DailyInfo {
    private ArrayList<SomeInfo> dailyInfo = new ArrayList<SomeInfo>();
    ...
}

class WeeklyInfo {
    private DailyInfo[] dailyInfo = new DailyInfo[7];
    ...
}


In most cases this would be the right object oriented approach, which by the way solves the problem of array of generic type.

Wednesday, October 7, 2009

m and n have switched on my keyboard...

The letters 'm' and 'n' have been switched. I type 'm' and it comes out as 'n'. I remember something about a virus so I run my anti-virus (no result) and search the web (some results).

       Cone om! I’n beconimg imsame!

It's so annoying. Maybe someone is fooling around with me.

A quick glance at another keyboard: it's not that 'm' types 'n' -- the keys themselves changed places... each sits at the other one's location. A quick pull of the keys, stucking them again back into their right position and everything is great!

After a short investigation it appears that my 6 years old son, who is using my computer for playing, accidentally popped out the 'm' and 'n', then put them again in place quickly before I'll notice. Well, almost in place... He didn't intentinally planned for giving me a hoax, though it came out quite a good one for his age.

Wednesday, September 23, 2009

Auto-unboxing hazard -- the three states of Boolean: TRUE, FALSE, and...

What do you say about the following code:

boolean isActive = (Boolean) pageContext.getAttribute(IS_ACTIVE);
if(isActive) {
// dosomething
}

If you are worried about the casting to Boolean in case where attribute IS_ACTIVE doesn't exist, don't worry, it's OK to cast null to any type, null stays null.

So, is it OK?

Well, no. The problem is with the auto-unboxing to primitive type boolean, which throws NullPointerException if the Boolean is null. Which is a bit hidden from the programmer who might miss this hazard when writing the code.

How should we fix it?

Is the following a decent fix:

Boolean isActive = (Boolean) pageContext.getAttribute(IS_ACTIVE);
if(isActive) {
// dosomething
}

If you ask "what's the fix?" - we turned the variable isActive to be Boolean rather than boolean. Which should eliminate any NullPointerException on the first line! But only in order to pass the exact same NullPointerException into the 'if'...

So, what about:

Boolean isActive = (Boolean) pageContext.getAttribute(IS_ACTIVE);
if(isActive.booleanValue()) {
// dosomething
}

Yes, you are right, same NullPointerException. Maybe now even more explicit.

We could go with:

Boolean isActive = (Boolean) pageContext.getAttribute(IS_ACTIVE);
if(isActive != null && isActive) {
// dosomething
}

But I believe this looks better:

Boolean isActive = (Boolean) pageContext.getAttribute(IS_ACTIVE);
if(Boolean.TRUE.equals(isActive)) {
// dosomething
}

Tuesday, September 22, 2009

Frameworks -- Explicit and Implicit Wiring

In any new project, there is that moment when you are reflecting whether a group of classes belong to the package "core" or "utils" or "framework", or whether you need all these three altogether.

The difference between utils, framework and core should be simple. Utils are the basic functions needed by everyone, mostly unrelated to this specific project. They are all stateless by definition, simple input and output, with no dependency with the project's structures. Utils can always be easily tested as stand alone. Core is the basic stuff. The stuff you would direct a new developer to learn first. It is project specific. It may include the basic types relevant for this project, interfaces, enums, project's basic exceptions, etc. Make sure to avoid making it a trash can. It's not the address for things without a context.

Framework is the tricky one of all three. As opposed to "utils", the role of "framework" as suggested by its name is more complex. A framework is a piece of behavior interacting with other code to represent a real, concrete, runtime behavior. Usually, even if built specifically for this project, it has some generic characteristics, it is written in a way that could be extended, or used in the future in other ways that we don't see currently. For this we use design patterns like strategy, command, visitor, and in fact almost any that you can think of, to create some kind of "dynamic behavior", or "dynamic wiring". Which means that the framework describes a behavior, but not entirely, only an exact usage can describe an end-to-end scenario. This is why frameworks are best explained with an example (while utils can be explained by what they simply do).


There are good frameworks and bad ones. EJB in its first versions for example was horrible (some don't like it till today, a first bad impression is hard to fix). JDBC is a good framework. Java-Servlets is a good framework. What makes good frameworks good is that people find them easy to use, they save development time compared to other alternatives, and you would usually find over time very few versions of the same good framework (and the new versions would be fully compatible with old code). Of course the question is how to achieve this simplicity, real contribution and long-run future compatibility.


When designing and implementing a framework, occasionally you want to make life easier for the user by doing something automatic for him, let's say pass the value of some field into another field with a relevant name convention -- thus the user doesn't have to write a single line of code! There is this trick in the framework which does it for him. Let's call it "implicit wiring". Alternatively, you may expose to the user a way to acquire the value and require him to pass it explicitly by writing his own code. Let's call it "explicit wiring".


In some cases the difference is not so obvious. Suppose you have a controller which may implement many kinds of behavior, if not implemented then a default behavior is used by the framework. When the number of different behaviors of this controller start to inflate, things become a bit obscure, unreadable, thus maybe "implicit". A better approach would be to break the controller to different interfaces and allow the user to implement the interfaces representing the relevant behavior for him, thus checked by the compiler that no method is accidentally left out, more readable and "explicit".


This discussion came out recently with my team member Effie.
We had a reference between two UI elements: "table" and "toolbar". I suggested that if "table" doesn't declare on its referenced counterpart "toolbar" then we will assume by default that it relates to a toolbar with some predefined name (e.g. "toolbar"). That way, I said, even if the user forgot to give a name for his toolbar, things would work nicely.

Effie's reaction was a bit frightening. (Well, not for someone who knows him). It is common in our work environment that a worker shouts at his boss. Which happened in this case. "I'm not working this way, if you want such a framework leave me out of it", was the part I can quote. Of course when he chilled out came the explanation. Implicit wiring is the base of all framework sins. I like such semi-emotional semi-professional reactions! And he was totally right. Think of someone trying to understand how the framework connects a toolbar to a table. And if he wants to add now another table and toolbar how can he do it? True, there is still the explicit way of referencing by name, but once I entered the implicit way, most cases would be using the implicit format which makes the explicit less known and less documented in examples. Also, implicit wiring tends to break over time, as at some point it may collide with something else and break old code. On the other hand, if you allow only the explicit way, all examples would present the explicit way, code would be always more simple to understand and maintain, and less prone for future incompatibilities. Even with the costs of higher efforts in the first implementation, explicit shall win.


Frameworks in their nature do things behind your back. Try to narrow this behavior as much as you can. Make things explicit as much as possible. Less to explain and document and more for your framework future compatibility.


Write? Rewrite? Use? - Thoughts on shaky frameworks

Java is a great language. A great framework, tool, environment, libraries, all of that. From the very beginning the designers of Java thought of almost anything. Well, almost. ResourceBundle didn't support UTF-8 till Java 6! A few bugs were opened on that during the years (4093632 from 1997, 4221013 nicely written, 4749531 begging, 4919638 and 6204853 giving a final attempt, probably missing some). But it took a long time for someone to listen.

Were they drunk those guys? localization with support only for ISO-8859-1? are you nuts?

Yes, you could use escaped unicode (like '\uXXXX'), but it's not readable. Yes, you could use a UTF-8 file and escape your unicode as part of your build process (native2ascii). Some IDEs (netbeans) volunteered to do this automatically for you. But this is still bad.

Luckily for us, in Java 6 you can construct a PropertyResourceBundle with a Reader, thus you can create a Reader based on UTF-8. Or maybe not so luckily? The ResourceBundle.getBundle still works the old way, you cannot ask it to use UTF-8, so they hacked only half way - what the point? (Yes, you can use the Java 6 ResourceBundle.Control class to control the creation of your bundles but it's so lame. I implemented it and it works, but amount of code needed for such a simple task is unreasonable).

Here comes the question: should we use this problematic framework or write our own implementation? After all, it's not rocket science.

Usually I tend to be very careful with suggesting "write your own version of it". Our development instinct is usually seeing the flaws in some existing implementation, convincing our boss that we must write our own new version of it. In many cases our new version misses some important parts that the preexisting implementation already handled. In some cases the drawbacks that we saw in the preexisting code are in fact design decisions required in order to deal with scenarios that we don't think of or ignore and may tackle us later. So when I do see some existing commonly used library I'm very careful before I decide it's not good for me.

I found this suggested implementation. Seem much easier than the way to do that with the bone thrown at us with Java 6.

Still, might be not so bad idea to implement the entire thing, load of resource bundle, by myself. I still hesitate.

Friday, August 14, 2009

Technology Optimism

At the time of massive cutoffs, transition of positions to low-cost centers and the sour smell of pessimism in the air -- I feel the spirit of Technology Optimism.

During the good times, the finest people with the brilliant ideas are sucked into the big corporations, tempted by nice salaries and all other perks. In many cases what they do in such positions is to work hard on projects that are later being shutdown. Let's admit, the big corporations are good at raising the money and selling the product, but when it comes to innovation, best innovative trick is to find the right startup to acquire. And this goes also for great innovative companies like google (GoogleMaps, GoogleVoice and many more are based on external acquisitions, see Wikipedia - List of acquisitions by Google).

There is a great advantage in a crisis, being a tool in reforming the market back to an efficient structure. We need more innovation and much more efficient companies.

Many brilliant people who have been back into the market lately are fed up working for giant dinosaurs, and start working on their own new startups. It may be hard at this point to raise the initial capital, but these startups are thin and efficient. And in a year or two we will start seeing the results with new technology domains that we couldn't imagine before.

Thursday, August 13, 2009

When a bug makes you crazy

This week I was sitting on one of those bugs which almost make you scream. Something is wrong, but you cannot find what creates this f-word behavior.

I was working on some web page example for some Taglib framework, but the page insisted on having an extra element that I didn't create. And when picked using FireFox, it pointed at a node in the XHTML that I'm definitely not rendering...

Step 1
Nothing in the code should make this happen. First suspicion is that I'm running an old instance, so I'm running a clean+compile and restarting the server, then when this doesn't change anything I'm adding a printout just to make sure. The new printout appears. Damn! I'm running the code that I'm looking at, but nothing there seems to be responsible for this result.

Step 2
I know that in order to debug I need a theory. But I cannot raise any theory, as clearly the result that I see is not something that is in the code... So I start playing (though I know it's not the methodic way for debugging, but I'm trying to play methodically). I find all places where I render this kind of element that is being rudely added where not belonged and I mark them each with a unique id. The id appears. Now I can identify the exact place that is responsible for this behavior, but I can't understand why it happens. An XHTML tag is added in a place in the document that surely I'm not printing.

Step 3
It took me some time. Maybe too much time. But I understand now that FireFox tree view of the page is cheating me... The element that FF is presenting at a certain place on the tree cannot be there. I'm not printing it there. Suddenly a strike hits me: GET BACK TO THE BASICS. Instead of using FireFox to locate for me the wicked node, let's view the source of the page. How simple and basic, though yet I spent about an hour before thinking about this simple thing.
And indeed, when viewing the page source I see that the problem is that I'm opening some HTML tag somewhere and not closing it, but FF closes it for me way beyond this point, creating a very strange node that I didn't create. In the treeview of the page FF presented a tag with a start and an end, while I accidentatlly opened a tag at some point and didn't close it. Now it's much easier to see the problem. And I also note that indeed FF showed that there are errors on page, with this error listed.

Moral

  1. When the tool you debug with shows something that you cannot explain, go back to the basics: tcpdump, sniffer, printouts. The debug tool may be misleading you!
    Believe only to bits and bytes, not to any fancy tool.
  2. If you are working on a Web page, first look at the "errors on page", if you always insist on first fixing these you will save valuable time.
  3. When a bug makes you crazy look him in his eyes, tell him that you will beat him. Don't show any weakness signs as these bastards know well how to recognize such signs.

Thursday, July 2, 2009

IE is a pain in the ass

Back in the old days when there were Internet Explorer (IE) and Netscape, everybody knew that it is very difficult to write something that would run perfectly on both. But since it was only two dominent browsers not many pointed the finger at IE. It was just that the two are different, life is challenging what could you say.


Today, when you have Opera and Chrome and Safari and FireFox -- ALL BEHAVING THE SAME -- and IE in his own realm, it is much easier to point the finger.

And here are some who do point the finger:

and there are more, just google for IE sucks or IE pain in the ass. Which it is, for most web developers.

It's nice to see that the other browsers do have a strict implementation according to the W3C standards, resulting with uniform behavior and ease of development. It says good things on the W3C standards being well defined and about the discipline of the coders of the other browsers, as opposed to IE.

Microsoft needs to drop IE altogether, start with a new code base and a new brand name, the current one is ruined.


Tuesday, June 23, 2009

JavaDay, JavaOne - Java Thoughts

I was attending Sun's Java Day this week, here in Israel. The main themes Sun is pushing are JavaFX and MySQL.

Some thoughts on both, as well as other topics.

JavaFX

Sun's interest here is clear. Every handset or any sort of device running JavaFX means more licensing fees for Sun. In fact, JavaME is one of the only Java environments which Sun's really see money from, at least for now. This would probably change in the future with much more agressive sell of JavaSE licenses for extra features and support, but still handsets is a very important addressable market, competing with others technologies such as the simple browser, Android, iPhone Objective-C, etc. Sun interest is to have as many applications as possible running on top of JavaME, JavaFX and LWUIT (the last two are a bit competing on the same square). More applications means more consumer power (consumers who want to run these applications) thus more pressure on the handsets manufectures to have JavaME and JavaFX on the handset, droping the required license fee at Sun's pocket.

All fine till this point. But now it comes to JavaDay event, or JavaOne conference in SF. These events shall reflect what interests the Java community, be judgmental, compare competing technologies. But instead it becomes more and more a marketing event for what Sun is trying to push. Thus, JavaFX catch very high percents of all sessions (even a session on Maven had to be called "Deploying JavaFX apps with Maven" or something alike to get in...) And it is totally lacking the critic perspective, comparing with other competing technologies such as Android, GWT, zool, YUI, Adobe AIR etc.

Is JavaFX interesting? probably yes, but not at the amounts poured at us.

As for the judgmental perspective, I'm missing in JavaFX the separation between content and style, without that this would be a step back. Does JavaFX work with CSS? not that I know of. Is there a similar alternative? The declarative approach of JavaFX is good, but why the choice of JSON-like declarations and not XHTML? The language is very close to Groovy, but not exactly the same (Groovy is from Spring creators), is there a path to consolidate these two new scripting languages? And why should we go with a propraietary environment and language, and not with W3C standards adopted by the browsers running on mostly all handsets? ... Yes, I know there are answers for some of the questions above, but in the huge time dedicated for JavaFX, alternatives, as well as known flaws and drawbacks, were not discussed.

Which brings me to the thought that independent Java events, such as
Devoxx, are a better meeting place for the community.


MySQL

This was another theme at the event. MySQL is a powerful tool, the regulator shall take it out of the hands of Oracle to preserve competition.


Java Reference App

Together with Ronen Perez, I was presenting a session called "Java Reference Application - putting all the buzzwords together" focusing on our selected libraries and tools.


Java Community and New Technologies

It's good to see all these smart people together. Being smart, people follow the trends and new technologies carefully, asking "what is it for me? how does it make my life easier?" In the past you could see people enthusiastic about any new thing, today you see people much more careful and reluctant. It's either that we are fed up with disappointments from previous "innovations" or that the pace of things require us all to be more cautious and conservative. This, together with the competition between technologies, requires new technologies to be well cooked and invest much more effort in getting us in.

Thursday, May 28, 2009

Technological Singularity

A singular point is a point in which the rules that define the spectrum around are no longer valid. In Mathematics a singular point is the point for which a function is undefined, in Physics, Gravitational Singularity means infinite gravitational field, known also to be a Black Hole.


Technological Singularity is the point of time when computers would be more inteligent than humans, thus creation of new computers and software programs can better be made by computers. Though sounds science fiction, something like the Matrix, I do know, as of today, of humans that are less inteligent than computers, one shall admit computers did part of the way.

The steps towards singularity in software engineering would be the creation of new software languages which are much more declarative rather than procedural. Computers would be able to get well-formed requirements, or constraints, to create the required piece of software. Prof. David Harel started talking about it back in 2000. Now the problem with our usual requirements is that they are not so well-formed, filled with holes and hacked with contradicting constraints. But what if a computer can identify the holes and contradictions and ask us what we really meant, then go and create the software. And maybe there is no need to ask us, since the computer knows better anyhow. The famous inventor and futurists Ray Kurzweil is speaking about technological singularity in his book The Singularity is Near with forecasts such as that by 2020 personal computers will have the same processing power as human brains and by 2030s Mind Uploading would become possible.

It's closer than you think. Declarative programming. Computers who understand requirements. Technological singularity. At which point the only occupation still relevant for humans would be lawyers, as computers cannot be mean enough for this job.

The future is surely an adventure. Some would see the upside potential of it, others may see the risks, which are there of course. For those and for those it would be good to read some advice from Daniel H. Wilson, on
How To Survive a Robot Uprising: Tips on Defending Yourself Against the Coming Rebellion.

Monday, May 25, 2009

Maven, Static Code Analysis, Code Coverage and more

Static code analysis and Code Coverage are becoming as basic as IDE syntax highlighting. Tools like FindBugs, Cobertura, Checkstyle, PMD, Eclemma and others, with plugins to Eclipse and Maven extensions, makes your life as a programmer more manageable, having Maven build a site for you with your code coverage results and following Checkstyle remarks in the IDE.

The title connects between things that are uncorrelated, except for being a measurement for modern Java development practicing. And of course Maven relates it all together also.

Today a Java programmer that knows only Java, even if very well, but intentionally ignores what's arround in the industry, e.g. sticking with good old Ant ("Why do I need this Maven, I'm doing just fine with Ant, just leave me in your mother") becomes a bit obsolete. The strength of Maven is that you can take a project with its POM.xml, and open it on another machine, even with another IDE that supports Maven.

So, to summarize.
As a programmer you are usually stressed and under pressure to close your tasks. Find some time to enhance your environment with the relevant Java Power Tools.

Sunday, April 12, 2009

Wicked Problems

Wicked problems in software design are problems that tempt you into a certain solution or design that seems reasonable and easy but turn out to be holey as a leach.

Mature developers and software architects know how to avoid wicked problems. Managers with lack of technical background may fall into such traps without even noticing and without realizing the trap even in retrospect, you may find a manager who would be very proud of a solution his group created for a wicked problem, investing in it a few man months, without seeing other alternatives of avoiding it or implementing it a bit differently with much less effort and side effects.

Straight solutions for wicked problems tend to be not only costly for implementing, but also for the long run, as the stitches sewed to close all holes tend to get unstitched, torn open.

Let me take you through a very small problem that I was dealing with, and turned out to be wicked.


Some background. In web applications we need occasionally to get info from the server according to user selections without turning to a new page. This is called an AJAX operation. There are several frameworks for supporting easy implementation of AJAX calls. One of which is YUI (Yahoo User Interface), which does on top of this all sort of other great things, supporting similar web experience on different web browsers.

YUI has a component for AJAX auto completion. The component is quite powerful and allows selections ranging from simple ones like this:



to more complicated, as this one:



In YUI the selection made is entered into the input-box and this is the information sent back to the server. We wanted to add the ability to send back to the server an ID instead of the selected value itself. This is useful since in many cases we want to present to the user meaningful text while the server really needs an ID. And we wanted it to work also for the multi-select version.

The solution seemed to be simply to add a hidden field and put the IDs there. The server would of course need to send in the AJAX reply the text to present in the list and input-box, as well as the ID per each entry. Making it part of the JSON reply is simple. Now, every time the user makes a selection we can add the ID into the hidden field, even for multi-select.

Simple and easy. We even found a few implementations like this on the net.

But this is not enough...

Since the user types his selection, he may type a selection without selecting (clicking on it) from the suggestion list. The user may also delete things after selecting them and then the hidden field needs to be updated. He may also retype characters into a selection made already, thus changing it to another, legal or not.

One thing came to our mind is that this feature needs to go with "Forced Selection" which means that the user cannot add things into the input-box without selecting them from the suggestion list. This may solve some of the problems. But not the deletion problem, we still need to take care of user deleting a value from the input-box. The only way to tackle the deletion problem is by populating the IDs hidden field only when the user leaves this input-box (when the focus is lost, i.e. in the "onBlur" event). Then what we can do is to loop through all values in the input-box, add a relevant ID for each in the hidden field, and display a warning for illegal values (for which there is no matching ID). The problem now is that at this point we may not have all IDs, so we need to go back to the server, in an AJAX call and ask for the IDs. And the values in the input-box must be unique, that is: each must represent exactly one ID (there cannot be two John Doe).

At this point we realized that we are going to work hard for a solution that would not bring much value to application writers, as they would need anyhow to implement a function on the server side for replacing textual values for IDs, and those textual values must be unique. So why don't just post the textual values back to the server as is, exactly as implemented originally by YUI.

Well, there is one reason for the hard work. And it is supplying warnings to the user while he types and not following post back. By checking whether all textual values has legal IDs we can warn the user for illegal values before posting the form. But then, one needs to decide whether this worth the investment, and whether it can work well.

We came to the conclusion that the people at YUI knew what they were doing. It is way too tricky to post back IDs. No, it's even more than that. It's wicked.

Now, we invested about half a day in investigating the problem and thinking of solutions, and then eventually decided to avoid this implementation. How many of us would do the same after investing a week in investigating?

A wicked problem is usually a problem that you'd better waive, avoid, abandon. Suggest other ways of doing it. Replace with another feature which is easiest to implement. The efforts of solving the wicked problem do not justify its value. Yes, a wicked problem is sexy, if you solve it you can become a true hero, it makes out a really neat feature. It is courage and experience, needed to realize the real effort for these wicked problems and to admit they do not worth it, even if some time was already invested in analysis and investigation. Or, to find the easier design, almost fulfilling the wicked problem, achieving most of the goals with much less effort.


Sunday, March 29, 2009

Sun's Future

Rumors on IBM about to acquire Sun has taken Sun's stock up recently. The idea of Sun being acquired were running around already for some months when Sun's stock was dropping to 10$ (e.g. here, from August 2008). Today Sun is traded back at about 8$, after jumping more than 60% in the past two weeks.

When Jonathan Schwartz, Sun's CEO,
announced the change of Sun's ticker from SUNW to JAVA, at August 23rd 2007, that was the beginning of the end. The price of the stock was around 19$ then, after visiting 253$ (!!!) seven years earlier. The main problem is that unlike Microsoft or IBM, Sun never succeeded in making money out of software. They had a history of starting software products and then shutting them down, and they never really cashed the success of Java. Sun is a company with technical excellence and innovative spirit, but for the benefit of itself and of the software market, it shall find its place within a company that knows how to cash out these qualities.

-------------
May 2009:
Well, by now we all know that it was Oracle eventually to buy Sun. Still keeping the above relevant. I'm surly wishing all the best for this couple. And for IBM as well of course.
-------------

Monday, March 16, 2009

Software Factories

Before the industrial revolution most of the products were made by hand, crafted. Is software manufacturing today more like a confection (ready made clothing) or more like "haute couture"?

The term "Software Factory" was created for describing the possibility of getting software requirements and sending them into a "factory" for manufecturing. (Do not mix that with a Microsoft technology with a similar name).

The challenge is that with software, customer needs may be very complicated. Can we just send the requirements into a "Software Factory" and get it done? (This in some way contradicts the idea of constant communication embedded in Agile Development.)

Think of airport control system that needs to address all kind of airports and equipment. Think of banking software that shall address different banks and communicate with all sorts of external interfaces. Can we create modules that are generic enough so that customization for specific customer needs can be done by cheap work force and without too much complications and investment?

Most software projects cannot be cloned. There is no customer that resembles another, requirements are different and the "physical" legacy environment is not the same.

Closets are also not all the same. Each customer may have different specific requirements. Nevertheless, most carpenters manage to stay scalable and address specific requirements by setting standards, such as several available sizes (you can order a closet of 2.0 or 2.4 meter height, however, 3.0 meter height would be a special order, would be processed uniquely and priced accordingly) and several available woods.

To achieve the ability of creating software as in "Software Factory", we shall:

  1. Narrow the options and alternatives. State clearly what can be built as a standard and what is a special order.
  2. Externalize a clear API
  3. Insist on always getting clear requirements before starting (did you see a carpenter starting to work on a closet before having all measurements?)
  4. Have core modules, easy to customize for very specific needs, with hooks and plug-ins for adding specific functionality
  5. Create a very strict and close way of customizing the product, allowing it to be done by cheap work force. Always prefer customization techniques which require less thinking. Customization shall not be art, it shall be very technical and strict, preferably with clear instructions.
  6. Both the core module and the customizable product shall be easily testable, each on its own.

I had a debate recently on whether the preferred technique for rendering raw data into HTML is JSP with Taglibs or XSL. Though XSL is very powerful and can do anything with raw XML at hand, I argue that a set of strict Taglibs with the instruction not to use Java code inside JSP makes it much easier to make this task in the mode of "Software Factory". In oppose to XSL, which is in some way an "art", using a strict set of predefined Taglibs is something that is much more narrowed, cannot handle all cases and special requirements, but can certainly provide most needs and most importantly, can be done by almost anyone, given clear requirements.

We are already in a period in which most organizations cannot afford having their software be "haute couture", they must settle on confection, ready-made, with some adaptations. Most software companies who would still manufecture their organizational software products as "haute couture" would not survive, unless in very specific and unique domains. When software becomes a commodity, like a cheap chip, the only way to produce it is in a "Software Factory" model.

Friday, March 13, 2009

Real Life Architecture

When designing a system one shall think of all possible scenarios and error cases. Ignoring a possible scenario may lead later to all sort of problems, ranging from crashes to logical errors (e.g. fulfilling a financial transaction without finishing the order process, so the customer is debited but would not get any product).

One thing that we shall bear in mind is that listing all possible scenarios does not mean implementing a solution for all possible scenarios. There are error cases that are quite rare or not-so-rare but very difficult to handle, maybe even require a whole different design approach. A possible solution may be to log the problem to a specific database for manual handling, or for a later amending batch operation. Such approach can save a lot of the hassle during all stages: design, implementation and maintenance.

I may rephrase the above rule: listing all possible scenarios is a MUST, however, implementing a solution for all possible scenarios as an integral part of your system is probably not always the best solution.

Usually implementing a fully-blown solution for rare cases doesn't really work, as it is not tested enough for all variants and nuances of the exact scenario, and when the rare cases do happen you see that some modifications shall apply. Taking the treatment of rare special cases outside of the system, to either manual or batch operation may thus be a wise thing to do.

I call this "Real Life Architecture" based on the famous article by Gregor Hohpe Starbucks Does Not Use Two-Phase-Commit, which appears also as a transcript at Joel Spolsky's The Best Software Writing I. Gregor argues that in real life we often use asynchronous messaging without worrying too much about error scenarios, which we do deal with when happen, in somewhat batch way. As an example Gregor goes through the ordering mechanism at Starbucks, its simplicity and efficiency.

Saturday, February 28, 2009

Be proud of your code!

I'm usually quite proud of my code. If I'm not, I keep polishing it. When I review code of my guys, one of the things I insist of is to have the person's name on his code. Like on Dexter Horton Building.

If the guy says: "but all I did here is just to add this one little function".
"Well," I say to him, "so add your name above the function".

If the guy says: "but all I did was to fix this line. I didn't really added any new line of code".
"Well," I say to him, "so add your name above the line that you fixed, with a date and explanation of the fix".


But if the guy says: "hmmm, I'm not sure I'd like to put my name here. I'm not sure it works so well". Then I jump and say "haha! this is exactly why I insist on having your name there. Not initials. Not your nick name. A name that we can trace back when you will be a big manager at IBM, so you better don't leave any bug there."



The building above is real. I took this picture myself (I won't let you know where it's located. If you're curious you would probably google it.) I use this picture when I talk about code review and my insistence on having the developer's name on his or her code. Alex from mistralzonline, already documented this picture as part of his talk on present and represent, at his blog "On Everything And Nothing In Particular".

Thursday, January 29, 2009

The risks of redundant code (or - Less is More)

One of the preferred refactoring methods of my choice is deleting redundant code.

I separate between excessive code and redundant code:

1. Redundant code is code that never runs:

  • Unreachable code
  • Unused classes, interfaces and methods
  • Commented-out code
  • Code that looks wrong, then you understand that it is indeed wrong, but is being lucky enough not to be called
  • Code that deals with cases that cannot happen
  • Code that deals with cases that could happen in the past, but now cannot
  • Code that is there for future cases, which are not occuring yet (and may be added sometime)

2. Excessive code is code that runs, but can be reorganized into less lines of code:

  • Unnecessary abstractions, unneeded levels of delegations
  • Copy-Paste that can be moved to methods, inheritance, templates

Both are bad and should be treated. But the first category, redundant code, is much riskier. The main risk of redundant code is that it looks innocent and useful, but it doesn't really work and it is never tested. In many cases you assume that there is some value in this code, so you keep it around, maybe it will become useful sometime. Well, most probably it will become useful by creating new bugs when you accidentally use it. Remember: this code was never really tested, just being there, so familiar, part of your code, does not make it something that works. And in many cases it confuses you, as you believe that a feature is already written, because the code is there, you only need to pass another value or take some code out of a comment. But this code was not maintained or tested for ages, if at all! How can you rely on it? Why keep it there in the first place?

My recommendation usually is to be very cautious with code that never ran and is just lying there, as it may be lying and not doing what it supposed to do.

Keeping unnecessary code requires you also to maintain these lines of code that you don't really need. Again, I say - get rid of it.

Thursday, January 8, 2009

Generic Software Mission Statement

Following my previous post on the subject, I created the following generic mission statement:


Produce quality code, on time, for the success of the company.

Yes, I know, it's VERY GENERIC, but as a general mission statement for software groups it's quite good.

The problem with a more specific mission statement is that it may miss the responsibility of some of your employees. I had a few years ago a small group dealing with projects for customer applications. In one of our business group talks, the business group manager threw at the entire group that the goal for the team in the following quarter was to achieve sales target of 1M$.


The problem was that it was a group of programmers, not sales people, and achieving sales target was not part of our responsibility. The manager was just pumping down to us his own target (probably adding 25%, just to increase our motivation). The results of this talk was horrible, people were going around thinking how to bring 1M$, instead of doing their programming tasks. It scared some and it totally ruined the motivation of most, who usually do not relate their code to money. Code is art, relating it to money makes it dirty. Instead of speaking of money it was much better to speak about features, projects and deadlines. Even setting for a programming team a target of number of customer projects to achieve is wrong. Mission and targets shall be focused on the responsibility area of the team. It's the manager's responsibility to hide all the rest.

Monday, January 5, 2009

Vision, Mission, Goals, Objectives and Mesurements

Year start is a good oppotunity to think about vision, mission and goals. I know that there are those cynical of you, who treat vision and mission as a waste of time. I tend to agree. It's a waste of time if you invest in it too much, and it may become a farce when you invest 15 minutes or more in explaining your vision or mission statement to your organization. Vision and mission are a great tool for saying something short and not too meaningful, but there are still important as they do shed light on your VALUES -- what do you value and where you are going to put your efforts.

The much more important are the goals and objectives. This is your opportunity to list the strategic achievements you want to bring. Goals and objectives should be SMART. That is: Specific (not vauge or too general), Measurable (state the measurement as part of the goal), Attainable (be realistic), Relevant (related to your vision, even if you don't have one yet), and -- Time-bound (otherwise it's like an exam without a time limit). There are, by the way, other interpretations for the SMART abbreviation but the main idea stays the same -- be clear and make the goals something that can be checked at a certain point of time and marked as done/not done.

SMART is smart to say but difficult to do, especially when you plan the future, which is what you do with setting goals. Let's take some examples:

  • For "Innovation", you may set the following goal: come up along the year with at least 5 new major (define major?) feature ideas, for which at least 3 would be judged as feasible and relevant to the market and at least one would be developed.
  • "Quality" is tricky. You may want to give bonus to the programmer who creates the fewest bugs, you may want to read before what Joel thinks on that.
  • "Investigating" new domain: what is the target goal to set? I usually set the goal as giving a lecture on the subject, at a certain agreed date. Usually it promises decent investigation of the subject. In some cases I add the requirement for documenting the material in our organizational wiki.

Setting strategic goals for the coming year/quarter/month is one of the most important tasks of a manager. Ask yourself, how you want your accomplishment powerpoint presentation to look like at the end of the period. Or maybe even better, prepare this powerpoint presentation ahead. Then set the goals and tasks that derived from it, aiming at minimum changes for your presentation.

Once you have the goals and objectives you can go back to the vision and mission, it would be much easier now to state them in 5 minutes. And if you don't find something strong enough go for "Bring qualitative value to the organization".