Tuesday, November 18, 2008

Time for Smalltalk

Öredev is coming up and I’ll be giving a talk called Time for Smalltalk. The title of the talk is supposed to imply that the time for Smalltalk is finally here. I claim this since the publicity of dynamic languages like Ruby and Python has paved the way for Smalltalk. Only a few hardcore developers are still resisting the power of modern IDEs, so the barrier of Smalltalk adaption is considerably lower than it was a in the beginning of the eighties when Smalltalk first arrived.

The reason developers in dynamic languages should switch to Smalltalk is that the Smalltalk environment is alive. You are working inside a running system and instead of constantly trying to create new worlds, the Smalltalk way is to modify the world to fit your needs. This metaphor fits a lot better with the way good systems are usually developed. Start small and let the system grow incrementally.

The liveness property of Smalltalk also gives you the ability to refactor the code in a safe way. At runtime I can just ask the system in what classes a certain method is implemented and then I can let the system rename it as I wish.

Three of my new colleagues from factor10 Jimmy Nilsson, Aslam Khan and Lennart Ohlsson will also be speaking at the conference.

Saturday, November 08, 2008

What should be in an application 2008?

Listed here are features that I want in any application. The features are separate from the domain specific service that the application is designed to provide.

Search

The feature that I want more than anything is search. Everything should be indexed: menus, toolbars, dialogs, windows, selection boxes, shortcuts, help files, configuration files, application components, objects, scripts, the works! It should be possible to make generic full-text searches for anything matching my criteria, but it should also be possible to make specific searches by category or tag. It should also be possible to save the searches for later.

Search should also be available in all places possible. It does not have to be a search field, it can be a selection box or a textfield. It should preferably be integrated into the components to help me out whenever it is possible.

External tools should also be able to search. Tools like Google Desktop and Spotlight, and Launchers like Quicksilver and Launchy must be kept in mind when designing for search.

Tags

Anything searchable should also be taggable. It is possible that my terminology is different from the one that the application developers have. I may also want to group things together that does not appear related to anyone else. It should of course be possible to assign multiple tags to the same thing.

Scripting

Everything should be scriptable. Whatever is possible to do in the GUI should be possible to script. This lets me create my own automated tasks that I can re-use later or share with other users. It should be possible to run and create the scripts both inside and outside the application. The scripts should not be limited to use application functionality, they should be allowed to call operating system commands or other applications. The scripts will thus also serve as plugins for the application.

As with search it is important to have external tools like Quicksilver and Launchy in mind, but when it comes to scripting the scope is wider and you need to think about command line interfaces and other external applications too. Provide many entries to your application.

Shortcuts

It should be possible to assign shortcuts to any action available in the system. This includes saved searches, tags and scripts. Shortcuts should allow Emacs-style multi-key-shortcuts, such as Ctrl-C, Esc-V, M.

Persistence

It should be possible to save the state of the application at any time!. It does not matter to me that a form or that whatever I’m doing is an invalid state. Perhaps I like invalid.

It should be possible to save it anyway. It should also be possible to take snapshots at any time and to reset the application to a previous snapshot at any time. Preferably it should also be possible to compare different snapshots with each other in a useful way.

All in all I want persistence to work like a versioning system giving me the possibility to move through history at my leisure.

Export – Import

Exporting is just a different flavor of persistence. It should be possible to export (persist) the application data into some format that is useful to another similar application. This format should naturally also be importable.

Since exporting is just a flavor of persistence I naturally want versioning of my exports to. Perhaps it’s a good idea to just use git as a persistence engine?

Validation

I mentioned validation above on persistence. Validation is a valuable tool in an application but more often than not it gets in the way. The validation should not force me to enter data in a specified order unless it is absolutely necessary. It is good and even helpful to provide hints and markers along the way. But let me work the way I want to work and stay out of my way.

The important thing with validation is that it should indicate an error as soon as it appears but it should not force me to do anything about it until whenever I try to do something fatal such as, to quote Simon Peyton Jones, launch missiles.

Wiki

I find it really helpful to be able to link things together in Wiki style. The need for this is very dependent on the type of application but I find it very useful to be able to relate one item to another when I commonly need them together.

Conclusion

This list is by no means meant to cover everything, but I think it is a good starting point for anyone who want to make a useful application that can evolve with time.

Friday, November 07, 2008

How (not) to buy books

If you, like I, read a lot of books from different areas you probably buy a lot of books that are of questionable quality. I used to do this too. Now, I use libraries instead. Some of the advice here will be specific to Sweden, since this is where I get my books, but you can probably find similar places where you live.

  • Find the book you want. If it is an English book Amazon is the place to go. If it is Swedish use Bokus or AdLibris. The value of these websites is that they provide a lot of information about the book, such as summaries, reviews and references to other related books. The related books are interesting since they provide you with options based on what others bought, the author and other people’s recommendations. All to help you find the best book for your topic.
  • Use the ISBN, title, author, etc and search in your local on-line library catalog. In my case it is the library in Staffanstorp. If you find it all is well, just reserve it and pick it up the next day.
  • If you don’t find it in your local library goto your country’s common library catalog. In my case it is called bibliotek.se. If you don’t find it here you will have to buy it, but I have found more than 90 percent of my books here lately.
  • If you find the book, go back to your local library catalog and make an Inter library loan (fjärrlån in Swedish). Make sure you say that you found the book in the common catalog and that you want it delivered to your local library unit. The book is usually delivered in about a week at the cost of 5 SEK.
  • If you like the book and think you will read it again, buy it. If you don’t, just return it and feel content with that along with saving a small tree, you didn’t encourage a crappy author to write another book :)

Monday, November 03, 2008

Notes on The Long Tale

The Long Tail by Chris Anderson is a book about what happens in a market where the cost of production and distribution becomes negligible. The long tail refers to a statistical distribution where the distribution curve never drops to zero.

Short-Tailed Markets

In a market where the costs of inventory are high, such as in a standard book store, the store can only hold a limited amount of products in stock. The store will naturally want to keep the best selling books in stock to maximize their profit. This is often referred to as the 80/20 rule. 80 percent of the sales come from 20 percent of the products.

The 80/20 rule and the inventory limitations changes the buying patterns of the customers since they will buy what is available instead of going to great lengths to get something that is hard to get or even completely unknown to them, thus re-enforcing the rule.

Long-Tailed Markets

The reduced costs of product inventory and distribution due to the Internet and Just-In-Time techniques is changing the rules. Amazon is reporting that sales from books that would not normally be kept in stock in a normal book store provides one third of the total market share. And the share is growing rapidly.

There are three things that enable the long-tailed markets: production tools that enable cheaper small scale production, cheap and simple distribution tools, and a new connection between producers and consumers.

Production

Cheap, simple production tools, such as Garage Band, iMovie, blogging tools, etc. enable enthusiasts to create acceptable music, movies, podcasts, articles, etc. at virtually no cost. And they do. The production in the tail is not driven by money. In the tail the drive comes from the need to express oneself and to have fun. People who do things for themselves instead of for money often produce better products.

Distribution

The digital media can be distributed via any of thousands of channels, YouTube, Vimeo, iTunes Store, Pirate Bay and DC++. Music and video are easily downloaded to iPods and other portable players. Books are available as audio books or available as PDFs to read on-screen or to print at home. Bloggers are writing millions of articles everyday, available to anyone, for free!

The Connection between Producers and Consumers

Google is The Start Page for the Internet and it enables the connection between producers and consumers. It also enables the consumer-to-consumer connection. The trust in advertising is steadily decreasing while the trust in individuals continue to rise. Google enables me to find like-minded people that are happy to give recommendations to anyone who is interested in what they do or are interested in. We are the critics in the Internet age.

There is so much information available that the need to filter is higher than ever. Google provides this filter with the assistance of numerous blogs and other social tools. The filter has moved from pre-production to post-production making it possible for us to choose what fits our needs instead of the needs of publishers that are ultimately driven by money and professional critics with different taste than ours.

But, the professional critics have not disappeared, they have just become less important. And in the abundance of information that the Internet provides it can still be a good choice to rely on external agents instead of trying to make all the choices ourselves (see The Paradox of Choice).

Saturday, October 25, 2008

TDD and LINQ to SQL

Microsoft has made the unfortunate mistake of not making System.Data.Linq.Table<T> implement an interface. If they had only done this it would have been easy to mock out the Persistence Layer when using LINQ to SQL.

Since it is a class and a sealed one at that, this is not an available path for TDD. What to do? If we can’t implement it we can adapt it. What is required for this to work is two interfaces: IUnitOfWork and ITable<T>, two classes LinqToSqlUnitOfWork and LinqToSqTable<T> and for testing purposes two additional classes InMemoryUnitOfWork and InMemoryTable<T>.

ITable<T> looks like this. I usually only include the methods that I need and add more by need.


   public interface ITable<T> : IQueryable<T> where T : class
    {
        void Attach(object entity);
        IQueryable<TElement> CreateQuery<TElement>(Expression expression);
        IQueryable CreateQuery(Expression expression);
        void DeleteAllOnSubmit(IEnumerable entities);
        void DeleteOnSubmit(T entity);
        object Execute(Expression expression);
        TResult Execute<TResult>(Expression expression);
        void InsertAllOnSubmit(IEnumerable entities);
        void InsertOnSubmit(T entity);
    }

IUnitOfWork looks like this with one accessor method for every aggregate in my domain model. I have only included SubmitChanges in the interface but it is entirely possible to include all the methods of DataContext here if you have the need for it.


   public interface IUnitOfWork
   {
       ITable<Player> Players { get; }
       ITable<Round> Rounds { get; }
       void SubmitChanges();
   }

LinqToSqlUnitOfWork looks like this. Every method wraps the sealed Table<T> in a LinqToSqlTable<T>.


public class LinqToSqlUnitOfWork : IUnitOfWork
{
     private readonly LinqToSqlDataContext dataContext;

     public LinqToSqlUnitOfWork(LinqToSqlDataContext dataContext)
     {
         this.dataContext = dataContext;
     }

     public ITable<Player> Players
     {
         get { return new LinqToSqlTable<Player>(dataContext.GetTable<Player>()); }
     }

     public ITable<Round> Rounds
     {
         get { return new LinqToSqlTable<Round>(dataContext.GetTable<Round>()); }
     }

     public void SubmitChanges()
     {
         dataContext.SubmitChanges();
     }

 }

The next class need is LinqToSqlTable<T>. As shown above the constructor takes a Table<T> as a parameter. All actual work is delegated to the Table<T>.


public class LinqToSqlTable<T> : ITable<T> where T : class
{
    private readonly Table<T> table;

    public LinqToSqlTable(Table<T> table)
    {
        this.table = table;
    }


    public void Attach(T entity)
    {
        table.Attach(entity);
    }

    public IQueryable<TElement> CreateQuery<TElement>(Expression expression)
    {
        return ((IQueryProvider) table).CreateQuery<TElement>(expression);
    }

    public IQueryable CreateQuery(Expression expression)
    {
        return ((IQueryProvider) table).CreateQuery(expression);
    }

    public void DeleteOnSubmit(T entity)
    {
        table.DeleteOnSubmit(entity);
    }
    ...

Finally we have the InMemory classes. InMemoryUnitOfWork works similarly to SqlToLinqUnitOfWork creating InMemoryTables that implement the ITable<T> Interface. The SubmitChanges method is left as an interesting exercise for the reader :)


public class InMemoryUnitOfWork : IUnitOfWork
{
    private readonly ITable<Player> players;
    private readonly ITable<Round> rounds;

    public InMemoryUnitOfWork()
    {
        players = new InMemoryTable<Player>();
        rounds = new InMemoryTable<Round>();
    }

    public ITable<Player> Players
    {
        get { return players; }
    }

    public ITable<Round> Rounds
    {
        get { return rounds; }
    }

    public void SubmitChanges()
    {
        //TODO
    }
}

In its simplest form the InMemoryTable<T> just uses a List<T> as storage, delegating all possible functionality to the list. A lot of methods are left out for brevity.


    public class InMemoryTable<T> : ITable<T> where T : class 
    {
        private readonly IList<T> list;
 
        public InMemoryTable() : this(new List<T>())
        {
        }

        public InMemoryTable(IList<T> aList)
        {
            list = aList;
        }

        public IEnumerator<T> GetEnumerator()
        {
            return list.GetEnumerator();
        }

        public Expression Expression
        {
            get { return list.AsQueryable().Expression; }
        }
   ...


This simple wrapper gives me the ability to create repositories for my classes that work for both LingToSql and with in memory collections. Here is an example:


public class RoundRepository
 {
     private readonly IUnitOfWork unitOfWork;

     public RoundRepository(IUnitOfWork unitOfWork)
     {
         this.unitOfWork = unitOfWork;
     }

     public IQueryable<Round> Rounds
     {
         get { return unitOfWork.Rounds; }
     }

     public void AddRound(Round round)
     {
         unitOfWork.Rounds.InsertOnSubmit(round);
     }

     public void ClearRounds()
     {
         unitOfWork.Rounds.DeleteAllOnSubmit(unitOfWork.Rounds);
     }

     public IEnumerable<Round> ByYear(int year)
     {
         var rounds = from round in Rounds
                      where round.PlayDate.Year == year
                      select round;
         return rounds;
     }
 }


This gives me the ability to test my domain classes at the relatively small cost of six new classes and interfaces. It also allows me to use the same test code for both unit testing and integration testing. Not bad for a days work :)

Thursday, October 23, 2008

Code Comments

I am a firm believer of Programming by Intent and TDD as a means to communicate effectively with my fellow programmers (current and future). I find that sometimes this is not enough and I have therefore started using the following code comments to improve the communication.

TODO: why, why not

The TODO signals that here is incomplete functionality here. The comment should be followed by a reason why this should be done and why it isn't.

WTF: who doesn't get it, what

A WTF signals that there is something I don't understand. It is a signal to whomever wrote the code to clarify its intent by refactoring or with a BECAUSE comment. Hopefully this code is written by someone else. :) The WTF should be followed by my signature and what I don't get.

BECAUSE: who, why

A BECAUSE signals that I am unable to express my intent in code and that I need help clarifying it. The comment contains my signature and what I am trying to express. Hopefully I or someone else will be able to clarify my intent later.

REF: link

A REF signals that this code is described elsewhere. The code may be an algorithm that is described somewhere on the web or in a book. The ref is followed by a URL or some other pointer that allows whomever is interested to find the information easily. I usually add the comment patterns as to-do regexps in my editor making it easy to navigate to them. I also let the continuous integration server parse for them to give me a list of things that needs attention.

The comments also provide the additional value of showing the quality of the code.

Wednesday, October 01, 2008

Notes on 'Secrets of Successful Speakers'

Notes on Secrets of Successful Speakers
by Lilly Walters.

Effective Communication

To be able to communicate effectively with your audience you need to have a clear message.
People will typically forget 90% of what you have said after one week. What are those 10%?

Decide what the purpose of your speach is. Write it down in one sentence. It should be:

  • Precise
  • Measurable
  • Reasonable
  • Relevant to your audience
  • Obtainable within your time limit

Don’t talk about something you are not passionate about.

Know and care about your audience:

  • Are they positive or negative?
  • What do they want?
  • Are they analytical, relational, dominating, expressive?

Developing the Presentation

  • Pick a simple easily remembered theme; one central idea.
  • Only use three to four main points. Every point should be relveant, independent and advantageous.
  • Create your own material.
  • Find a suitable structure: Story, Problem-Solution, Analogy, Acronyms.
  • What, Where, When, How, Why and Who?
  • Edit without mercy. No one ever complains that a speach is too short.
  • Give it a good title.

The Presentation

  • Attention: Be silent, look at the audience, joke, surprise.
  • Convince: Ethos, make them like you. Pathos, make them laugh or cry. Logos, substantiate your position.
  • Remember: Repeat
  • Practice