Feel like a geek and get yourself Ema Personal Wiki for Android and Windows

30 March 2010

Joel on Software - a summary: 2001.

This is a summary for the blog by Joel Spolsky, Joel on Software, volume 2001. The summary for the years 2000-2010 can be found on the Joel on Software summary index page.


Don't grow faster than you can find talented people. Some things need talent to do really well, but talent is hard to scale. Having the talent create rules for the untalented ("The Methodology") results in very low quality. -- Big Macs vs. The Naked Chef

Everything you ship to customers should be produced by the daily build process. -- Daily Builds Are Your Friend.

Never let people work on more than one thing at once. Programming is the kind of task where you have to keep a lot of things in your head at once. Therefore task switches take a really, really, really long time. -- Human Task Switches Considered Harmful

A company with a personal voice is attractive, because we are humans. -- Spring in Cambridge.

It makes no sense to optimize software by reducing the size of it, since storage is cheap, but programmer's aren't. -- Strategy Letter IV: Bloatware and the 80/20 Myth.

Architecture Astronauts add so many levels of abstraction that the resulting ideas are completely useless and incomprehensible. They throw bombastic whitepapers at problems that don't need to be solved. -- Don't Let Architecture Astronauts Scare You
If you want something to be The Next Great Thing it has to be more than architecture, it has to enable things that people really need. -- Are the Groove Designers Architecture Astronauts?

If your business plan includes projections from IT research firms, you better start planting tomatoes. -- Blogpost on 2001/04/18

Eating your own dog food can be disgusting, but that is precisely why you have to do it. -- What is the Work of Dogs in this Country?

If Microsoft were to concede the slightest point in an anti-trust case, hundreds of independent software companies would see this as their opportunity to enter Microsoft's markets. -- Michael E. Porter's Competitive Strategy
(Actually the point this article is trying to make is "you should analyze your competition and try to guess how they will react to your move", but I found the former sentence somewhat more appealing.)

Good software, like wine, takes time: probably ten years to become really good. Take this into account in your business model. -- Good Software Takes Ten Years. Get Used To it.

Fixing bugs is only important when the value of having the bug fixed exceeds the cost of the fixing it. The advantages of fixing a bug are: better reputation, less time wasted with tech support, you might charge more for the product. -- Hard-assed Bug Fixin'

If it's a core business function - do it yourself, no matter what. -- In Defense of Not-Invented-Here Syndrome.

VB is not cool because your code doesn't have {'s and }'s. I can live with the shame if it means I'm more productive. -- Working on CityDesk, Part Three

Nowadays a good programmer spends a lot of time doing defensive coding, working around other people's bugs. -- Working on CityDesk, Part Four

Joel points the reader to "Guidelines on Writing a Philosophy paper" by Jim Pryor. This article has some important points on writing, such as:
Don't write using prose you wouldn't use in conversation. Make the structure of your article obvious. Pretend that your reader is lazy, stupid, and mean.

Be pragmatic in your choices and don't necessarily follow the lastest hype. -- Working on CityDesk, Part Five

The stricter the API is about its input, the more likely the code is going to work in funny situations. -- A Hard Drill Makes an Easy Battle

Modern programming languages might give the impression that you don't need to understand the underlying concepts anymore. But this is not true. Some of the biggest mistakes people make even at the highest architectural levels come from having a weak or broken understanding of a few simple things at the very lowest levels. -- Back to Basics.

If you're not in a position to force changes to the development process, you still can initiate improvements. 1. Just do it yourself. 2. Find the people who are willing to improve and capable of it, and get them on your side. 3. Let bad programmers solve their own problems, this will occupy them for months and prevent further damage. 4. Get Away From Interruptions. 5. Keep doing your normal work to avoid bad reputation. -- Getting Things Done When You're Only a Grunt.

NHibernate: SQL query error

A unittest failed with this exception from the MSSQL CE provider:
System.Data.SqlServerCe.SqlCeException: There was an error parsing the query. 
[ Token line number = 1,Token line offset = 34,Token in error = ) ].
The SQL statements are generated by NHibernate, so this was a litte bit confusing. 

Fortunately, there is logging. And an excellent viewer.

The generated SQL statement does not contain any values to INSERT. This is logically correct, because the entity class does not contain persistent properties itself: it only contains two mapped collections:
public class HL7v3InfoMap : ClassMap<HL7v3Info>
{
    public HL7v3InfoMap()
    {
        Id(x => x.Id);

        HasManyToMany(x => x.FunctioneleEenheden)
            .Access.CamelCaseField()
            .Cascade.All();

        HasManyToMany(x => x.DataTypen)
            .Access.CamelCaseField()
            .Cascade.All();
    }
}
In this case the mapping was not finished yet, so the problem solved itself when I added more properties. But I also have cases where the class does not have any persistent properties of itself, for example a class that is an abstract base class.

I don't know a better solution than adding a dummy property to the entity.

21 March 2010

Joel on Software - a summary: 2000

This is a summary for the blog by Joel Spolsky, Joel on Software, volume 2000. The summary for the years 2000-2010 can be found on the Joel on Software summary index page.


The goal of your software company is not to solve some specific problem, but to be able to convert money to code through programmers. -- Converting Capital Into Software That Works.

Interviewing. It is much, much better to reject a good candidate than to accept a bad candidate. You’re looking for people who are smart, and get things done. -- Guerilla guide to interviewing.

Every decision should made by the person with the most information, which is probably the team working on the software, not the manager. -- Command and Conquer and the Herd of Coconuts.

Companies need to keep their employees loyal by treating them well, not by enforcing blind loyalty though a contract. -- NDAs and Contracts That You Should Never Sign.

Realistic schedules are possible and are the key to creating good software. -- Evidence Based Scheduling.

Performance reviews and incentives simply can't work in the workplace. It's insulting and demeaning and lowers morale. -- Incentive Pay Considered Harmful

Don't rewrite an application from scratch. There is absolutely no reason to believe that you are going to do a better job than you did the first time. -- Things You Should Never Do, Part I.

UI design for programmers
A user interface is well-designed when the program behaves exactly how the user thought it would. Pick the simplest possible model. -- Controlling Your Environment Makes You Happy and Figuring Out What They Expected.

Design is the art of making choices. Don't give the user options that are not relevant to the task he wants to perform.-- Choices.

Well-designed objects make it clear how they work just by looking at them. -- Affordances and Metaphors.

Consistency is a fundamental principle of good UI design. Emulate popular programs as closely as possible. It may not show off much creativity, but in the long run it makes users happier. -- Consistency and Other Hobgoblins

Design your software so that it does not need a manual. Minimize text in the UI. -- Designing for People Who Have Better Things To Do With Their Lives.

Design your program so that it does not require a tremendous amount of mouse-agility to use it right. Prevent the need for pixeltinkering -- Designing for People Who Have Better Things To Do With Their Lives, Part Two

You shouldn't ask people to remember things that the computer could remember. And: show respect towards your users. -- Designing for People Who Have Better Things To Do With Their Lives, Part Three

Find out which features support the most important user activities. The Process of Designing a Product.

Give knowledge workers space, quiet, and privacy to maximize productivity. -- Where do These People Get Their (Unoriginal) Ideas? See also: Bionic Office.

You need 1 tester for every 2 programmers. -- Top Five (Wrong) Reasons You Don't Have Testers

If you start a company, pick one of: 1) Amazon model (invest a lot and get big fast) or 2) Ben and Jerry's model (grow slow but steady and durable). -- Strategy Letter I: Ben and Jerry's vs. Amazon

Any business plan that calls for making a computer that doesn't run Excel is just not going anywhere. -- Strategy Letter II: Chicken and Egg Problems
Google obviously did not read this article before introducing Google Wave.
Joel provides other example of the chicken and egg problem in Wasting Money on Cats

Eliminating barriers to switching (both ways) is the most important thing you have to do if you want to take over an existing market. -- Strategy Letter III: Let Me Go Back!

To get programmers to work for you: make the workplace attractive, eliminate obstacles, and provide benefits which are more valuable than the money they cost. --Whaddaya Mean, You Can't Find Programmers?

"The Joel test" is introduced as a rogue alternative for testing your company's coding quality with twelve simple yes/no questions. In practice the Joel test seems to do quite well. -- The Joel Test: 12 Steps to Better Code

Writing specs
When you design your product in a programming language instead of human language, it takes weeks to do iterative designs instead of minutes. A spec saves time communicating. With a spec, it is possible to make a schedule. Writing a spec is a great way to nail down all those irritating design decisions, large and small, that get covered up if you don't have a spec. -- Painless Functional Specifications - Part 1: Why Bother?

Specs have a disclaimer, one author, scenarios, nongoals, an overview and a lot of details. It's ok to have open issues. Text for particular audiences go into side notes. Specs need to stay alive. -- Painless Functional Specifications - Part 2: What's a Spec?

You need a dedicated "program manager" to write the specs. The Program Manager is both technically and socially gifted: he has to get along with all people involved, like customers, sales and the developers. -- Painless Functional Specifications - Part 3: But... How?

If you want readers for the specs you wrote, follow these rules. 1. Be funny. 2. Write understandable. 3. Write as simple as possible (be "unprofessional"). 4. Review. 5. Don't use a template. -- Painless Functional Specifications - Part 4: Tips

The only time a company would want to change its name, from something people recognize to something completely new, would be if it had such low brand equity that the old name was a liability. -- Blog post on 2000/11/12

Use a bug tracking system. Every good bug report needs exactly three things. 1. Steps to reproduce, 2. What you expected to see, and 3. What you saw instead. -- Painless Bug Tracking

A good architect only uses tools that can either be trusted, or that can be fixed. -- Up the tata without a tutu.

09 March 2010

The easiest way for custom View folders in ASP.NET MVC

To change the directory where ASP.NET MVC looks for the views, create a custom ViewEngine and add this ViewEngine to the ViewEngines collection, replacing the old one.

This CustomLocationViewEngine will replace the default "Views" search location with a custom one:
public class CustomLocationViewEngine : WebFormViewEngine
{
    private string location;
    public CustomLocationViewEngine(string location)
    {
        this.location = location;

        base.MasterLocationFormats = locationFormatsFrom(base.MasterLocationFormats);
        base.ViewLocationFormats = locationFormatsFrom(base.ViewLocationFormats);
        base.PartialViewLocationFormats = locationFormatsFrom(base.PartialViewLocationFormats);
    }

    private string[] locationFormatsFrom(string[] orgLocationFormats)
    {
        return (from l in orgLocationFormats select l.Replace("Views", location)).ToArray();
    }
}

Assign a new instance of this class to the collection in global.asax.cs, in Application_Start:
ViewEngines.Engines.Clear();
ViewEngines.Engines.Add(new CustomLocationViewEngine("Mvc"));

The reason for me to change the default view directory, is that I don't like the default setup where the Controller, the View and the Model all reside in seperate directories. In large applications it is very inconvenient switching between the three parts of the MVC pattern. I have good experiences with this approach:
Create a directory for each controller and put the Controller, Views and Models there. If the directory gets too large, the Controller is too large.

06 March 2010

A C# CQRS framework AgrCQRS

To get some grip on the topics DDD, CQRS and Event Sourcing, I have started on a framework for CQRS applications and a sample (questionnaire) application which uses the framework. It is heavily inspired by the resources mentioned below. You can find the project on its CodePlex site: http://agrcqrs.codeplex.com/

Lately a very interesting pattern has emerged, the Command Query Responsibility Segregation (CQRS) pattern. It is actually an existing software pattern that is being applied on a higher level, that is a framework level. It comes down to seperating the domain model and domain logic from the read model. The pattern gives the advantages of high scalability and removes quite some concerns which are introduced by using the domain model for querying, for which it simply isn't well suited.

CQRS and Event Sourcing seem to go hand in hand. Event sourcing is a way of storing state by storing the stack of events that led to the state instead of storing the state itself.

Watching/reading list:
Remember CQRS is an evolving pattern, and there is few frameworks or guidelines which you can grab and start to use (yet). The framework I created on CodePlex can be used, but needs polishing.

The AgrCQRS framework is written for the .NET framework 3.5 in C#.