Term of the Day: Principle Of Least Surprise

The principle of least surprise (AKA POLS) simply dictates that the interface to any given entity (method, for instance) should exhibit the bevahior that is least suprising to the user/programmer when there are conflicts or ambiguities between members of said interface.


Example:  


Let’s say that the following are true…


The following classes exist: Person, Address, People


Person has the following attributes: SSN, Name, Address


Person.SSN is used to identify Person instances


People is a service that manages a set of Person objects


People has to following methods: Add(Person):void, Get(SSN):Person


 


Now let’s say Joe programmer is using People to describe his blooming social life…


Joe says:


myFriend = new Person()


myFriend.Name = “John”


myFriend.SSN = 9999999999


myFriend.Street = 10101 Victory Lane


myFriend.City = San Mango


myFriend.Address.State = Texas


myFriend.Address.Zip = 93940


 


Then he says:


friends = new People() 


friends.Add(myFriend)


…Now Joe’s friends include a reference to John…


 


Later Joe wants to write a letter to his friend, so he says:


myFriend = friends.Get(999999999)


 


If the People class adheres to the POLS, the address of myFriend should be that same as it was when he added it to friends. 


 


Now here’s a scenario that we see on occasion that will give Joe a nasty surprise.  The author of People decided that states are implied by zip codes.  Instead of bothering with the State value that’s passed into People, it just stores the Zip code and gets the appropriate state based on the Zip repository that People’s author went through so much trouble to create.  Unfortunately for Joe, when Joe entered the data he had been reminiscing on his own address in central California and he accidentally entered his own Zip.  Now Joe’s lost contact with his only friend (poor Joe).


 


As a result, myFriend looks like this:


myFriend = new Person()


myFriend.Name = “John”


myFriend.SSN = 9999999999


myFriend.Street = 10101 Victory Lane


myFriend.City = San Mango


myFriend.Address.State = California


myFriend.Address.Zip = 93940


 


Person’s Add() looks like a setter and the Get() looks like a getter.  The interface does nothing to communicate that somewhere in between there is an implied mutation based on Zip.  This behavior would therefore violate the POLS.


 


The example may seem a bit silly, but I’m sure we’ve all run into similar scenarios more than we’d like to admit.  This concept isn’t new, just often ignored.


 

Related Articles:

Post Footer automatically generated by Add Post Footer Plugin for wordpress.

About Joshua Lockwood

I code stuff and people pay me for it.
This entry was posted in Best Practices, Principles. Bookmark the permalink. Follow any comments here with the RSS feed for this post.

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>