Premack’s Principle Applied To Software

Friday, February 12, 2010 by K. Scott Allen
8 comments

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
8 comments

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
0 comments

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
17 comments

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
8 comments

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.
by K. Scott Allen K.Scott Allen
My Pluralsight Courses
The Podcast!