Monday, June 1, 2009

When once is not enough



P1030473

D.R.Y. principal of software design is based on one of the most natural and intuitive ideas: once is enough. D.R.Y. stands for "Do not Repeat Yourself" and applies not so much to code, but to representing ideas and concepts in software systems. Every piece of knowledge, decision, policy, algorithm, etc., should be represented exactly once, and no more than once. The concept of D.R.Y. was introduced by Andy Hunt and Dave Thomas in "The Pragmatic Programmer" book, first published in 1999.
However, the D.R.Y. principal is extremely hard to consistently follow in programming practice. Commonly, the same algorithms will be implemented independently in different parts of the system, for different objects, and same concepts will be implemented differently (with the idea of producing the same results) at multiple parts of the system. Lots of bugs happen when a concept needs to be changed, but not all representations are modified, or modified in the same way.
A common case is dealing with a simple list of things. It is natural to want to store a list as database entries. It makes sense to store a list of things in the database table. It also makes for easier report generation when working strictly from the database data.
However, when writing code, it is desirable to have each item in the list available as an enumerated type. It simplifies the code greatly to be able to work with an enumeration. It also works well with the fact that the list is not going to change often, thus saving on database accesses.
But storing the list as a database table and as an enumerated type directly violates the D.R.Y. - this list is now defined in two places. More importantly, it is now a very likely source of bugs - one of the two sources defining the list can be updated without the other. Depending on the usage, these bugs can be extremely hard to track.
While there is no good solution that restores the D.R.Y. principal, there are ways to automate checking for synchronization of two implementations. A unit test can verify that two lists are in sync and warn about a potential mismatch.
To verify that two lists are the same, the unit test must that retrieve all items from the database and ensure that each item has a corresponding enumerated type. It should also run through all defined enumerated types and verify that there is a correspond database entry. Here's the pseudo code:

List dbItems = retrieveAllFromDB();
foreach (item : dbItems) {
EnumeratedType enum = EnumeratedType.get(item.id);
Assert.valid(enum);
}


foreach (EnumeratedType enum : EnumeratedType.getAll() ) {
DatabaseItem dbItem = retrieveFromDB(enum.id);
Assert.valid(dbItem);
}
While this is not quite as good or right as following the D.R.Y. philosophy, it does prevent many errors, and makes bug hunting a lot simple and more predictable. One of the more substantial drawbacks is that it requires more code, and more maintainance. Still, it is miles better than simply defining the same objects multiple places.

Saturday, February 7, 2009

Inspiration for teamwork




Teamwork


Some thoughts inspired by a recent discussion on Community vs Personal Credit at door64.com
Particularly in high-tech industry, teamwork and knowledge-sharing makes organizations productive. On the other hand, the appreciation of others and the benefits of social standing in a group are the most important motivations for a lot of employees. Relationships with colleagues make people either happy and productive, or miserable and unmotivated at work.
Many organizations work very hard to increase productivity by improving the employee motivation. A lot of thought goes into designing clever compensation schemes that align personal financial interests of employees with organizational performance. However, the bonuses and the raises happen very infrequently, usually once a year, while motivation is needed every day of the week. In addition, money is not a strong motivation for everyday performance for most people. These schemes take a lot of effort to create and execute, but ultimately fail to deliver on their goal of inspiring the employees.
Significantly less effort appears to be devoted to managing the social structure in the organization. Cooperation is not particularly rewarded, and the office jerk regularly gets ahead. There are hardly any programs that reward knowledge sharing with individual performance credit. It is normally up to each individual to persuade, cajole and bribe their coworkers into teamwork, against the carefully designed organizational incentives.
Fortunately, it is not very hard to get many people to cooperate. Many are happy to join the team and cooperate, because that is what makes people feel good. People prefer to work together even if HR-designed financial incentives suggest that it is better to strive for individual credit, rather than cooperate with others.
Still, an organization that figures out how to reward cooperation and knowledge-sharing will enjoy the highest employee productivity and a reputation for a happiest place to work.

Sunday, February 1, 2009

Scrum on a Wednesday






Wednesday is Monday I


There is a huge pull to perceived firsts and lasts. People make New Year's resolutions and buy the most expensive January's gym memberships. Lots of unsuccessful diets start on an already-stressful Monday, or on the first of the month (less stressful, but why wait?).
It is not just personal, it's business, too. New projects start on Mondays and deliveries are scheduled for Fridays, which are shown to be the least productive days of the week. Even worse, finishing up a job is often scheduled at the end of the year - Christmas holidays and all.
Mondays and Fridays are the worst days to make decisions under pressure: it takes time to get into the work flow after the weekend, and it is harder to concentrate after 4 days of hard work, than it was, say, on day 2 of the week. The productivity is highest in the middle of the week, Tuesday through Thursday. Mondays and Fridays are the least productive days of the week.
Lots of Scrum implementations start their iteration on a Monday and finish on a Friday. The beginning and end of Scrum iterations are when most meetings and decision-making occurs. The hardest and most error-prone work of the iteration - the work that does not go through a normal test cycle - is routinely scheduled to occur on the least productive days.
Planning and release are arguably the most important parts of the iteration, they set the tone for the success and productivity of the iteration, and the entire project. Would not it make sense to give these meetings a prime spot in the week, when the concentration is highest and the team has had a chance to get into the flow and is not mentally preparing for the weekend?