OdeToCode IC Logo

Premack’s Principle Applied To Software

Friday, February 12, 2010 by K. Scott Allen

Wikipedia lays out David Premack’s principle in laymen’s terms:

Premack's Principle suggests that if a student wants to perform a given activity, the student will perform a less desirable activity to get at the more desirable activity.

Many people grow up under a rigorous application of the principle. Parents around the world tell kids to “finish your homework before you play outside”, and “finish your vegetables* before you eat desert”.

 

fruitsandveggies

Did you ever wonder if the “no pain, no gain” line of thought drilled into us since grade school allows for a high level of friction in software? Users are willing to accept pain, and creators subliminally dish it out.

This is my theory: we allow business software to have high levels of friction because employees are predisposed to slog through undesirable activities inside software to get a job “done”, or just get paid (a highly desirable activity). Thus, with limited resources, business will always favor features over usability.

What do you think?

* The discerning reader will notice that the Imperial Stormtroopers featured in the picture are bearing fruit - not vegetables. However, section 4 of the artistic license granted to me as the owner of this blog includes a clause that allows pictures of Imperial Stormtrooper action figures to appear in any post, even when it risks creating cognitive dissonance. Pictures of Jar Jar Binks are still strictly prohibited.

What’s Wrong With This Code #24

Wednesday, February 10, 2010 by K. Scott Allen

Sometimes the simplest solution introduces a bug.

Let’s say there is a ListBox in WPF (or Silverlight) displaying bowlers* and their bowling scores:

 <ListBox ItemsSource="{Binding Bowlers}" >
     <ListBox.ItemTemplate>
         <DataTemplate>
             <StackPanel Orientation="Horizontal">
                 <TextBlock Text="{Binding Name}"/>
                 <TextBlock Text="{Binding Score}"/>
             </StackPanel>                             
         </DataTemplate>
     </ListBox.ItemTemplate>
 </ListBox>

Behind the scenes, a view model includes a Bowlers property for the binding to work.

public IEnumerable<Bowler> Bowlers 
{ 
    get
    {
        return _bowlers;
    }
    set
    {
        if (value != _bowlers)
        {
            _bowlers = value.ToObservable();
            // ... Raise property changed event
        }
    }
}

The property uses a ToObservable extension method that works in either Silverlight or WPF.

public static class ObservableExtensions
{
    public static ObservableCollection<T> ToObservable<T>(this IEnumerable<T> items)
    {
        var collection = new ObservableCollection<T>();
        foreach(var item in items)
        {
            collection.Add(item);
        }
        return collection;
    }
}

So far everything is working. Bowlers appear on the screen, and as new bowlers get added to the collection …

_bowlers.Add(newBowler);

… they magically appear in the display.

The Change

Now someone wants the bowlers list sorted with the highest score appearing at the top of the list. Sounds like a simple change to the Bowlers property:

public IEnumerable<Bowler> Bowlers 
{ 
    get
    {
        return _bowlers.OrderByDescending(bowler => bowler.Score);
    }
    set
    {
        // same as before ...
    }
}

At first glace, the new code works and the bowlers appear in sorted order, but something is wrong! What will break?

Hint:

Bowlers added with _bowlers.Add(…) never appear in the display. Why is that?

 

* Of the ten pin variety - not the spinning kind.

Upcoming Events

Monday, February 8, 2010 by K. Scott Allen

Here are some events I’ll be speaking at over the next couple months:

DevTeach

Toronto / Mississauga March 8-12. DevTeach stands for Developers Teaching. It’s a conference done by developers for developers. This annual event offers the elements of an international conference and the elements of a community event. Sessions include both presentation material and, whenever possible, hands-on training. We like to describe this event as the Developers Festival. Find out who should attend at this link. Check out the top ten ways to convince your boss to let you go this event. DevTeach is about becoming one of the best developer by getting training from the best in the industry.

Scandinavian Developer Conference

Göteborg, Sweden March 16-17. Whether you are someone learning development in Java, .NET or IBM i or you are an experienced user of these technologies for 10 years or more, there are lot of great information to be shared with everyone.

In addition to technical sessions, we will also have tracks with presentations about the Development Process and Methodology: Agile Methodology, Test Driven Development, System Engineering, Architecture, Project Management, Best practices, "Agile in the Organization". We will also have tracks about hot topics like Cloud Computing, Testing, Web Development and Mobile Solutions. At the Conference there will also be a track of Emerging Technologies presented in cooperation with ThoughtWorks ( www.thoughtworks.com )

DevDays 2010

DevDays is being held at World Forum in Den Haag March 30-31. DevDays 2010: the biggest Microsoft event in the Netherlands for software development and software architecture. Every year, thousands of professionals visit DevDays to get completely up-to-date with all recent developments in their area of expertise in two days.

DevConnections

Las Vegas April 12-14 2010. Developers from around the world will gather at the world famous Bellagio, for the Microsoft Visual Studio Conference & Expo, ASP.NET & Silverlight Conference & Expo and SQL Server Conference & Expo. You can be a part of this exciting event while you enjoy one of the most stunning hotels on the Las Vegas Strip at a great conference rate!

Thoughts on an MVVM Rant

Tuesday, February 2, 2010 by K. Scott Allen

I stumbled across “A vent abount MVVM Development” thanks to a tweet from @peterbromberg. Excerpt:

What really irritates me is that I am forced to waste so much time on how to try and figure out how a complex User Interface will work together with a suitable "ViewModel" all for the sake of being more "testable".  I could cobble together a pretty darn good application and still be able to split up the work among User Interface and code-behind developers.  I think adopting a non-industry standard, seemingly "best practices" ideology just because it seems 'cool' and it's "there" is the wrong approach to application development

MVVM Rockstar Ah, MVVM! MVVM is the rock star who packs the house at every XAML event. It’s in books, blog posts, and podcasts. You can’t swing a dead laptop without hitting someone who is spouting about the virtues of model-view-viewmodel. With so much hype, there’s bound to be backlash.

Does MVVM deserve the hype?

Short answer – no.

An Alternative?

You’ve got a complex UI with lots of rules, and you reject the MVVM best practice crap the whiteboarding architect is jamming down your throat. You’re gonna be … pragmatic!

void SaveButton_Click(object sender, RoutedEventArgs e)
{
   if(ThisIsValid)
   {
       if (ThatIsValid)
       {
           IsDragging = false;
        
           if (DraftCheckBox.IsChecked.HasValue &&
               DraftCheckBox.IsChecked == true &&
               ItemList.SelectedItem != null)
           {
               DragDropTarget.Children.Clear();
               SaveSomethingToWebServiceAsDraft();
           }
           else
           {
               DoSomethingElse();
               EmptyAllControls();
           }
       }
   }
}

Managing a complex UI by jamming code into event handlers results in something spectacular – as does throwing a bucket of water on a raging grease fire. Afterwards the fundamental problem of complexity (or fire) still exists – and it’s even worse than before!

Doesn’t MVVM Take Care of Complexity?

I’d argue that MVVM doesn’t solve the complexity problem by itself. Neither does SOA or object databases or tomorrow's next big thing. They all help - but they don’t make complex requirements disappear. At some point you have to roll up your sleeves and work on a design that manages the complexity at an acceptable level for your team, your skill level, your business, and your environment. Experience plays a key role here because it’s all been done before. Breaking complex things into simple, composable pieces requires practice with abstraction techniques and knowing where to apply the right amount of encapsulation.

One drawback to the MVVM hype is how the hype drives people to one solution for every problem. The truth is there are lots of tricks to managing a complex UI, and some of them are dead simple and have built-in tooling support. Here is a sample:

  • User controls and custom controls
  • Behaviors (underutilized, IMHO)
  • Triggers and visual states
  • Events and event aggregators

The trick is to pick the right tool for the job. 

So What Can MVVM Do For Me?

I think MVVM does help to manage complexity and and produce maintainable code. I’ve had success with MVVM. Like every separated presentation pattern it divides the varied concerns of a user interface. You can’t dismiss the MV* type patterns as pie in the sky architecture –they’ve served the industry well for decades.

What makes MVVM different? Why is it shiny and new? I think it’s because MVVM’s raison d'être is data binding.  It’s easy to dismiss MVVM as just another UI pattern, but binding does give MVVM a slightly different flavor (a bit salty at times, but that’s just because of the static typing). If you’ve already been using a separated presentation pattern, it’s the data binding capabilities you need to understand and leverage. Data binding is quite powerful in WPF and Silverlight. You can perform amazing feats with little effort and without sacrificing encapsulation. Giving up on data binding is giving up on many of the advantages in the platform.

Proper use of MVVM also gives you a testable chunk of code. I think it’s strange that the MVVM rant dismisses the work needed to make a complex UI testable. I’d think a complex UI would need more testing than a simple UI.

On the other hand, I did just read “How a stray mouse click choked the NYSE & cost a bank $150K”, so I might not be thinking clearly.

Wrapping about Collections

Monday, February 1, 2010 by K. Scott Allen

Mark Needham’s “Thoughts On Software Development” is a great collection of blog posts. Last year Mark wrote “Coding: The primitive obsession”, and challenged the idea that the primitive obsession anti-pattern is just about overusing low level data types like string and int.

The most frequent offender seems to be the creation of collections of things which we then query to find specific items elsewhere in the code. More often that not we'll also perform some custom logic on that particular item.

At its most extreme we might extract each of the items in a collection and make use of them separately. This somewhat defeats the purpose of the collection.

When this happens it often seems to me that what we actually have is a series of attributes of an object rather than a collection.

Mark goes on to describe how wrapping a collection can often create a more useful abstraction, then points to his debate in Wrapping collections: Inheritance vs Composition. It’s a good read.

I’ve been wrapping collections a bit myself lately, and it’s not too hard to create a custom collection that is both feature rich and descriptive of the problem it solves using composition. For example, let’s say you need to keep a collection of Stamp objects and support INotifyCollectionChanged.

public class StampCollection : IEnumerable<Stamp>, 
                               INotifyCollectionChanged
{
    public StampCollection()
    {
        _items = new ObservableCollection<Stamp>();
        _items.CollectionChanged += ItemsCollectionChanged;
    }

    public void AddStamp(Stamp newStamp)
    {
        /* logic */

        _items.Add(newStamp);
    }

    public void RemoveStamp(Stamp stamp)
    {
        /* logic */

        _items.Remove(stamp);
    }

    public IEnumerator<Stamp> GetEnumerator()
    {
        return _items.OrderBy(stamp => stamp.Something)
                     .GetEnumerator();
    }

    IEnumerator IEnumerable.GetEnumerator()
    {
        return GetEnumerator();
    }

    public event NotifyCollectionChangedEventHandler 
        CollectionChanged = delegate { };

    void ItemsCollectionChanged(object sender, 
                                NotifyCollectionChangedEventArgs e)
    {
        CollectionChanged(this, e);
    }

    readonly ObservableCollection<Stamp> _items;
}

Yes, it’s a bit of code, but it:

  • Gives you complete control over the surface area of the API compared to inheriting from ObservableCollection<T> or List<T>
  • Allows precise control over adding and removing objects (validation, perhaps updating fields).
  • Becomes a more descriptive part of the domain
  • Is not to be confused with a rap collection.

KISS Your ASP.NET MVC Routes

Monday, January 25, 2010 by K. Scott Allen

A little bit of thinking and compromise can remove unnecessary complexity from the routes in an MVC application.

For example:

Morgan’s web site has authenticated users,and Morgan decides the URLs for managing users should look like /morgan/detail. Morgan adds the following code to register the route:

routes.MapRoute(
    "User",
    "{username}/{action}",
    new { controller ="User", action="Index" }
);

Morgan runs some tests and it looks like there is a problem. The User controller is getting requests for /home/index. Oops, that request should have gone to the Home controller. Fortunately, Morgan knows there is all sorts of whizz-bang features you can add to a route, so Morgan creates a route constraint:

public class UserRouteConstraint : IRouteConstraint
{
    public bool Match(HttpContextBase httpContext, 
                      Route route, string parameterName, 
                      RouteValueDictionary values, 
                      RouteDirection routeDirection)
    {
        var username = values["username"] as string;
        return IsCurrentUser(username);
    }

    private bool IsCurrentUser(string username)
    {
        // ... look up the user
    }
}

The constraint prevents the User route from gobbing requests to other controllers. It only allows requests to reach the User controller when the username exists in the application.

Morgan tweaks the route registration code to include the constraint:

routes.MapRoute(
    "User",
    "{username}/{action}",
    new { controller ="User", action="Index"},
    new { user = new UserRouteConstraint() }
);

Morgan runs some tests and everything works!

Well …

Everything works until a user registers with the name “home”. Morgan goes off to tweak the code again...

STOP!

As a rule of thumb I try to:

  • Never use advanced routing features like constraints
  • Always stick to a URL like {controller}/{action}/{id} or {controller}/{id}/{action}

Sometimes you have to go break those rules, but let’s look at Morgan’s case. If Morgan was happy with a URL like /user/index/morgan, then Morgan wouldn’t need to register any additional routes. The default routing entry in a new MVC application would happily invoke the index action of the User controller and pass along the username as the id parameter. Morgan could also go with /user/morgan and use a simple route entry like this:

routes.MapRoute(
    "User",
    "User/{username}/{action}",
    new { controller ="User", action="Index", username="*"}
);

No constraints required!

The KISS principle (keep it simple stupid) is a good design principle for routes. You’ll have fewer moving parts, consistent URL structures, and make the code easier to maintain.

Silverlight and ASP.NET MVC Don&rsquo;t Serve the Same Master

Tuesday, January 19, 2010 by K. Scott Allen

contrast I’m flipping between MVC and Silverlight projects when a startling contrast starts to emerge. It’s not the obvious contrast between stateful and stateless. It’s a subtler contrast in design.

If you poke around in a new MVC project, one of the first pieces of code you’ll run across is the code to register the default route. It’s in global.asax.cs, and looks like this:

routes.MapRoute(
    "Default",                                            
    "{controller}/{action}/{id}",                         
    new { controller = "Home", action = "Index", id = "" }
);

This snippet relies on some of the recent features added to C# – extension methods and anonymously typed objects. It obviously draws some inspiration from Ruby on Rails, which builds on top of the dynamic, malleable Ruby language.

Compare that code to the code you’ll see when you open up just about any Silverlight control.

silverlight code

Well, you don’t actually see much code because the code is swept underneath a carpet of regions. This happens quite often in Silverlight, and I think it’s because developers are embarrassed to write lines and lines and lines of code to define a single simple property. It’s the elegance of RPG combined with the verbosity of COBOL.

public bool IsDropDownOpen
{
    get { return (bool)GetValue(IsDropDownOpenProperty); }
    set { SetValue(IsDropDownOpenProperty, value); }
}

public static readonly DependencyProperty IsDropDownOpenProperty =
    DependencyProperty.Register(
        "IsDropDownOpen",
        typeof(bool),
        typeof(Foo),
        new PropertyMetadata(false, OnIsDropDownOpenPropertyChanged));

 

I realize IsDropDownOpen isn’t just a simple property. It’s a dependency property, and dependency properties hold many great and magical powers. Data binding in Silverlight (and WPF), for example, is wonderfully feature rich and easy, but it comes with a price. Instead of writing one line of code …

public bool IsDropDownOpen { get; set; }

we need twelve!

The contrast isn’t in the number of lines of code, however. The contrast is in who the frameworks were designed to serve.

MVC is for Developers – Silverlight is for Tools

The MVC framework is designed for developers who write code. This fact is obvious in the API design and how the team fights for programmer friendly features like the new HTML encoding block syntax. The MapRoute code we saw earlier is just one example of many. The MVC framework took inspiration from platforms that are popular today because they favor convention over configuration and essence over ceremony. These are fancy terms for keeping things simple and readable.

Silverlight is designed for tooling. Visual Studio, Expression Blend, and other XAML, code, and art editors. I’m not saying we get rid of the tools. We need the tools for the feedback and capabilities they provide when building effects, animations, and irregularly shaped objects. But, it seems the developer’s life gets more difficult with the addition of every feature.

The Next 5 Years

I’d be surprised if another language doesn’t come along to become the de facto standard for the code behind XAML files. A language that is just as friendly to programmers as it is to XAML. A language that makes writing code for System.Windows fun, simple, and readable.  Maybe it will look like …

depprop bool IsDropDownOpen { get; set; }

… but smarter people then me can figure out the syntax. I just know there has to be something better.