Archive for the ‘Design’ Category

Conceptual coherence in software design

There’s no doubt about it, a good design is hard to find.   But design is critical in software engineering, just as in hardware engineering – bridges, skyscrapers, iPads, anything in the physical world.  Design affects almost every aspect of product development and its costs – and in software, the most costly one is maintenance. 

I always try to take extra time in the design phase to ensure that I’ve got it right, since I find that with a good design, everything is easier – from the start.

clip_image002How do you know if you have a “good” design?   After all, no one in the world can sum up the essentials of good design in a meaningful way for everyone.  And rather than empty academic prescriptions — “flexible, layered, blah blah blah” — I tend to use a series of acid tests whenever I’m coming up with a software design.  For instance:

  • Does the design meet the needs of the project?
  • Is it flexible and extensible enough to meet the likely needs of the business moving forward?
  • Can the development team pull it off easily to meet committed deadlines?
  • Is it conceptually coherent?  Would someone easily understand it, or would it be an effort to explain? 

There are others, too; but in this post what I want to talk about is near and dear to my heart: whether a design is conceptually coherent, and whether it affords easy use. 

Conceptual coherence

Sounds fancy, but what this really means is: “does it make sense?”  Do the concepts “stick together?”  (From the Latin, co-, together, + haere, to stick.)   If you’ve factored your design into classes and entities, do they make sense at a high level?  Can the classes, components, and services in your design be easily understood and used by other developers?  Or do developers have to understand and master details that should really be hidden from their sphere of concern?

A good design will make it easy to create robust, working software:

  • Classes and components map directly to real-world entities
  • Object model is easy to use and supports real-world scenarios (containment, iteration, etc.)

Let’s look at each one of these aspects in turn.

Classes and components map to real-world entities

The classes and entities you create in your design should map almost 1:1 to real-world entities.  Name your classes and entities in terms that end-users understand; use vocabulary familiar in the solution domain.  We programmers are generally such a smart lot that we tend to invent alternate realities, populated with their fantastic devices and widgets. Sometimes we lose sight of the real one, and that eventually have to explain ours to someone else in order for them to use it.  Avoid this like the plague!  Keep it simple: classes and components should model “things” in the real world.

An astute reader pointed out that this is very similar to the concepts of domain-driven design, which is true:  see additional links at the end.

clip_image004Say you’re developing the My Golf Genius application, which will allow golfers to track their play on courses across the world, and will use massively parallel service-oriented clustered computing architectures in the cloud to apply brilliant heuristic analyses to captured golf rounds, bettering the game of the average Joe by over 8 strokes! 

Your classes, objects, and entities should model real-world things like golfers, clubs, courses, holes, tees, strokes, handicaps, and so on.   Even if the implementation seems trivial, create and keep entities separate if that’s the way we think about them in the real world.   In code, classes and objects are super-cheap to create and manage these days in all aspects, from compilation to memory footprint to runtime.  The benefits of conceptual clarity far outweigh the shortcuts. 

For example, our My Golf Genius application architect needs to keep track of the number of strokes per hole during play;  he could reasonably store the number of strokes as an integer StrokeCount in a MyGolfApp.Hole class.  After all, it is a “count” – and counts are integers or longs, right?  It’s design overkill to create a whole object to represent each stroke, right??

clip_image006

Not so fast.  What happens when you need to extend your successful My Golf Genius application to provide stats on how your success in sand saves correlates with the time of day, the weather, and the stock market trends that day?  You don’t have this info:  you only have “StrokeCount” for each hole.   The problem is that "StrokeCount” is really a rollup of the real data. The solution is, of course, to have a list of Stroke objects, each of which can be any legal type of stroke, such as a PenaltyStroke or a SandStroke.  You can even add Drives and Putts – which of course, derive from MyGolfGenius.Stroke.  

If the architect of My Golf Genius had started out simple, he would have captured the reasonably relevant details of what really happens on the golf course: a series of strokes are taken on each hole by a golfer.  Extending the application to capture stroke detail – which of course enables enhanced analytics for Joe the Golfer –  would then be a straightforward task. 

clip_image008

An exception to this rule might naturally be  an “extreme” design, such as a high-performance computing system or any system where memory, storage, or performance requirements might require a tailored approach.  Few systems are like this.

The model supports real-world scenarios

It’s important beyond all that the models and classes and entities you come up with are usable.   They should work together easily and make it difficult for developers to screw up.   A lot of this happens naturally if you have composed your entities according the “looks like the real world” directive above.   Developers can interact with your model in a straightforward way to access and use entities in the system. 

For instance, we’d certainly be happy to see a clear model like this, which every developer is sure to understand:

clip_image010

Avoid creating leaky abstractions,” where the user must understand underlying implementation details or “gotchas”  in order to use your object model correctly.   The developer’s mental image of what’s happening must match what the objects are doing in software;  if there’s a disparity, the developer doesn’t really understand what’s going on.

Conclusion

Model your designs after the real world, and your solutions will be easy to create, easy to use, and easy to test.  By not inventing an alternate world in software, the team will have a ready common language of objects between them, with an existing understanding of how they interrelate and function.  In addition, other stakeholders such as business analysts and testers will find it easier to relate to the system.

***

More reading

  • Joel on Software: The Law of Leaky Abstractions
    Abstractions “leak” when you have to understand the underlying implementation details in order to use them.
  • Domain-Driven Design,” Eric Evans (Amazon.com)
    The book that started it all: four stars, well-loved by its readers. 
    “Readers learn how to use a domain model to make a complex development effort more focused and dynamic. A core of best practices and standard patterns provides a common language for the development team.”
  • Domain-driven design (Wikipedia.com)
    ”Domain-driven design (DDD) is an approach to developing software for complex needs by deeply connecting the implementation to an evolving model of the core business concepts”
  • The Secret to Designing an Intuitive UX: Match the Mental Model to the Conceptual Model (UXMag.com)
    An analog in user interface design – again, the paradigm of matching existing mental models. 
    “The secret to designing an intuitive user experience is making sure that the conceptual model of your product matches, as much as possible, the mental models of your users”
Advertisements

Better UX: application workspaces

[tweetmeme source=”KeithBluestone” only_single=false]Lately I’ve had some questions and thoughts about software usability, specifically in the area of desktop software personalization:   why do I have to care so much about where I compute?  

  • If I’m writing a book, why can’t I just sit down at any of my computers, open it in Microsoft Word, and work on it? 
  • Why are all my browser bookmarks and favorite sites different on each computer I log into?   If I install Firefox – or Internet Explorer — on a new computer, why do I have to go through and re-set all my favorite options and settings?  
  • When I install my favorite blogging software (Windows Live Writer), why do I have to re-create all of my blog accounts on the new computer?  And re-import a copy of my glossary (quick links)?  Why can’t I just “log in” and have everything set up the same, on every computer? 

And so on, down a long list of applications.  Why do we have to care so much about the where in computing, so often? 

Looking backwards

I think it’s part cultural artifact, part technological artifact, and part “chocolate ice-cream factor.”  The cultural aspect is that it’s always been done this way: why change?  The technological aspect is we simply don’t have well established frameworks and programming paradigms to provide usable identity-based support in our apps, especially desktop apps (“rich clients”).   The chocolate ice-cream factor is that people don’t realize how much easier it would make computing in their everyday lives.

imageChocolate ice cream factor: when people turn down choices simply because don’t realize how really good it can be — because they’ve never had it before; the status quo is good enough. Chocolate mixed with ice…  and cream?  Yeccch.

I coined this term in the late-1980’s after University Microfilms, where I worked as a software lead, spent $70,000 on a study by a high-falutin’ strategy consulting firm in Boston to tell them that no, people didn’t really want to read magazines on computers in gorgeous high-resolution, but “were fine with” a plain text transcription only (the existing format).  Eventually common sense prevailed… but still.  

“If I had asked them what they wanted, they would have said ‘Faster horses.’ ”
— Henry Ford

So I say to the product management visionaries, CTO’s, and chief software architects of the land:  provide personalized workspaces in your applications. Don’t do it for me; do it for your users, who will thank you a million times over.

And do it to be competitive with web applications, who are rapidly eating your desktop lunch. 

“In other words, the desktop is simply the means by which a user loads a browser. It’s a gateway. The value is not in the desktop anymore. It’s in the browser, which is the new desktop, in terms of real functionality delivered.”
Google competes for the future; Microsoft, the past (CNET, October 2009)

Next-gen Windows?

MicrosoftMicrosoft could bestow this vision on the world by designing an application-based “virtualizable workspace” – say, in a next-generation version of Windows — which would transparently virtualize your documents.

Imagine logging on to any Windows 2012 desktop in the world and having Windows customized exactly like your personal home desktop theme!  Not to mention having your documents securely and transparently mirrored on the desktop and in your document folders.  If workspace-enabled client applications are installed on the local machine (FireFox, QuickBooks, whatever), they would behave exactly like they did on your home desktop.  Awesome!

OK, you can put the top of your head back on now.  Tell me this wouldn’t help Microsoft in the fight against the browser invasion…

Or Microsoft could innovate in the .NET framework arena, and marry user information (an authenticated user profile) with a filesystem proxy which writes to “a cloud.”  (See code snippet below.) No more local, file-based filesystem — or only by special request, via special API, or by advanced users.  For existing legacy apps, it might even be pretty easy to retrofit them into this new storage paradigm.

Aside: I saw recently Microsoft’s introduction of Windows Live MeshimageNow this is a particularly boneheaded example of Microsoft’s technobfuscation of useful features.    (I just made that word up especially for WLM.)  First of all, I, a 30-year veteran of technology, cannot understand without drilling into it what the hell is going on and what I really have to do to use it.  It’s all hidden behind marketbabble and hype.  Mesh??  I don’t need a mesh – I need my files and folders!  For a clean, clear-headed rendition of filesharing that really works, see Dropbox.com (watch the excellent 2 min intro video).

For the record, a primary definition of the word mesh is “something that snares or entraps.”  Nice.

imageI haven’t studied how Apple’s iOS conceptualizes application storage, but I wouldn’t be surprised if theirs is pretty close to the right way.  One thing is for sure: users of iPhones and the iPads never have to worry about a “filesystem.”

Microsoft, are you listening?

Design notes

Let’s think for a brief minute about how this vision might be realized, at the level of software design and architecture.

Remember who you're dealing withPersonalization is enabled by having an authenticated identity: at the very least, a currently logged-in user profile.

The application workspace is the stuff the user’s working on, whatever is produced by the application:  files, projects, documents, etc.  A “workspace” is an easily graspable paradigm for the user – read: better UX — as well as an architectural abstraction that works extremely well in software.

Imagine the joy of “logging into” any Microsoft Word installation, on any internet-connected PC, to find that Word has instantly configured itself with all your favorite options, toolbars, and settings!  Priceless.

Implemented properly in code, the workspace as a storage provider abstraction completely isolates and protects the application from the physical details of where the documents and settings are stored.

At the same time, the workspace concept opens up a world of flexibility: the user’s workspace can be stored in “the cloud” – pick one – or via a central corporate web service, in a database, or even on a local filesystem if needed.

In fact, it makes offline workspace access a snap, since a local workspace can be easily synced with a central master as needed.   It makes backup a model of simplicity, since the workspace is the unit of backup, not a whole bunch of disparate, messy files & settings.  Sigh…  good design makes everything easy.

But the net effect is that the design lets the user work efficiently wherever the app is installed,  just like the incredibly successful model of a web application.  I can’t help but think this would be a significant competitive advantage in today’s marketplace.

FireFox, are you listening?

image
Now that’s a workspace

Executing a framework strategy

The problem with implementing personalization and location-independence in desktop apps is in the framework – or specifically, the almost complete lack of it.  There just aren’t built-in facilities to either Windows or .NET to do this kind of stuff.

The Microsoft .NET stack, as wonderful as it is,Microsoft .NET provides no additional built-in storage abstractions beyond those of the Windows file and folder.  Instead, each Microsoft developer or team must venture into the wilds of software-land and cobble together a custom implementation of the personalization and workspace concepts, involving both an identity model and a remote storage provider model. 

For one, it can be very expensive.  From my experience, it’s possible only in more well funded teams – that is, if Management in its infinite wisdom even decided it should be done in the first place.  Number two, the level of complexity in design and implementation is such that only the most technically elite teams could pull it off well, while maintaining commitments to project schedule.

For those companies and teams that can pull it off, they will reap the benefits of a “wow” factor from their users.  In addition, with the proper architectural guidance, a single implementation can be leveraged across an entire product portfolio.

It’s a compelling vision.

Some example code

A simple little example, where an “AppWorkspace” framework-style class implements .NET-compatible replacements for file and folder manipulation.  I imagine an authenticated user profile, attached to the current thread context, would be obtained by any of the available services out there, from Windows Live to OpenID.

// current practice = locally bound files
using (File f1 = File.Open(@"C:\MyStuff\mystuff.doc", FileMode.Create))

{

    // write user stuff to local file

}

 

// proposed concept: location-independence – no “C:”

using (File f2 = AppWorkspace.File.Open(@"mystuff.doc", FileMode.Create))

{

    // write user stuff to omnipresent “workspace”

}

Conclusions

Identity-aware, personalized, location-independent computing just plain old helps us get things done.   Because we don’t have to worry about where we’re computing, we – the users — can always focus on the task at hand: the document or blog post, the PowerPoint or the poem.

Today, legacy paradigms still haunt the modern desktop domain.  Until all applications can be effectively written in a browser (HTML 5, anyone?), there will still be a need for locally installed rich desktop applications.   As developers, we should implement truly personalized experiences, freeing the average user from having to think about physical location and – horrors!  a file system.  It’s just the right thing to do – it takes the user experience to a new level. 

And in case, there’s anyone alive today who does not understand that the new game in town is user experience (UX), then I have three words for you:  Apple Computer, Inc.   So then it’s decided:  let’s allow our users to log into any Internet-connected computer, and have their applications behave exactly as they did on the home machine.

Now that’s what I would call progress.

***

More reading and references

  • DropBox.comGoogle-esque in its clarity and simplicity.  And it just works beautifully!  I use Dropbox to sync files between about four or five PC’s.   Best of all, it’s free!
    “Dropbox allows you to sync your files online and across your computers automatically.”
  • Windows Live Mesh.  Microsoft’s new offering Confusing to me – if anyone has an experience to relate, please share it with us. 
    “Working on one computer, but need a program from another? No problem. Use Live Mesh to connect to your other computer and access its desktop as if you were sitting right in front of it.”
  • How "Windows Live" Is Obscuring Some Actually Good Products (LifeHacker, October 2010)
    “Microsoft has some cool products hiding behind ridiculously confusing names. Users of the very nifty  Live Mesh file and desktop syncing beta, for example, were told their service shuts down in March 2011. Where should they migrate? Windows Live Mesh, of course.   
    “Microsoft is emailing Live Mesh beta users and explaining how they can transition their files to Windows Live Mesh. It involves not a small bit of re-configuring the folders you want to sync, the settings you’d like for each synced folders, and waiting while your folders all move over to the new Windows Live Mesh servers….
    But it’s the naming, and duality of names, that puts people off—people including your Lifehacker editors, if I do presume to speak for most of us. The fact that somebody pulled the trigger on a mass user email saying, essentially, "Live Mesh is dead, so use Windows Live Mesh" is pretty astounding. To then require that users pull off what amounts to a manual transition of folders they wanted to set-and-forget for syncing is just salt in the weirdly worded wound.

Afterthoughts: design practices

In case there’s anybody still reading:  you have too much time on your hands, get a job!  Here are a few off-the-top-of-my-head thoughts about how a team might go about designing a virtualization solution.  It’s not rocket science, but… 

A core best practice that I always try to follow in new designs and architectures is: don’t reinvent reality.   Software designs and architectures are best when they reflect the way things really are.   If you’re in the banking vertical, your domain of interest includes people, tellers, accountants, accounts, deposits, withdrawals, and so on.   It’s easy to express a banking solution in the same language;  in fact it’s a hell of a lot easier, since you the architect and your posse of developers didn’t have to come up with a whole new set of objects – which is what most teams do, more or less. 

No, in good design, types of items in real life typically map directly to classes in code-land.    Things that can happen in real life become methods in code.  It simplifies life for architects, developers, and testers:  basically anyone who has to work with code.   Everyone understands the code structure and its classes, because they’ve seen them all before – in “real life.”

In the case of application workspaces and personalization of desktop applications, “real life” says the user is truly one and the same person, no matter where she sits down (logs in).  The “identity-aware application” might reflect this by having a current user profile

Likewise, the user has – in general – one set of files and documents they’re working with:  this is the user workspace.   The workspace proxies the Windows filesystem, looking exactly like it, and enabling centralized, one-shop storage and retrieval of  user information (profile), preferences and configuration settings, and any documents or content items that the user was involved in creating.    Like web apps, it would seem that all file paths would have to be “root-relative,” and not refer to a specific physical directory; an exception would be thrown otherwise.

The metaphor in software design

[tweetmeme source=”KeithBluestone” only_single=false]One major problem with software today is usability: user interfaces are difficult to use, obscure, confusing, and frustrating.   Why?   Because they do not present consistent metaphors to the users, who don’t understand what the software is doing.

Metaphor, metaphor, on the wall

Quicken check formAn interface metaphor represents the user’s conception of what is going on.  UI coherence is achieved if the user’s mental model mirrors what’s going on in the software.

As in life, software interface metaphors should be simple, common, and relevant.

An early example was Intuit’s Quicken bill payment software:  Quicken presented check-writing and bill payment functionality using the metaphor of an ordinary checkbook.

How radical!  Making software in the model of real-world things!  If only more software was made as easy to use as Quicken…

The checkbook and its checks are familiar to all of us — well, most of us.  As a result, we immediately understand what the application is doing and find it highly user-friendly.

Poor design strips context

An impaired metaphor – a poor design — for check-writing might present fields in a table-like layout, labelled “number”, “payee” and “amount” and “date.”  Think spreadsheet.  (Trust me, it has been done.)

Tabular design-inappropriate metaphor

In this interface design, almost all the aspects of normal, real-world bill payment  have been stripped out.  The process has been reduced to a simple task of data input.  Bland and tasteless, isn’t it?

So what, you might say.  When writing a check, everyone has to enter the check amount and payee anyway — it’s just a few fields of data.  What’s the big deal about the "check" form and all these fancy “metaphors?”  Seems like a big waste of time to me.

Well… no.   Check-writing is just one aspect of managing finances on a computer.   There are a whole host of other activities that need to be addressed, including managing the register, searching for items, reconciling the “checkbook,” and reports.   We already have a conceptual framework for doing most of these things in the physical world.

What are you, the developer, going to do?  Re-invent the wheel for each concept and activity by providing new, “de-natured” modern-age mechanisms for each — a form, a field, a listbox, a grid?   Or will you create familiar models for your users?

Encapsulating familiar metaphors in self-contained packages – user interface controls, for instance – promotes re-use across the codebase (lowering SDLC costs) and a better, more consistent UI (looking and behaving the same everywhere).

Affordances

Affordance is another key usability concept mentioned by Don Norman in his excellent Design of Everyday Things. An affordance suggests or directs the appropriate action.

A good example of a design with a prominent affordance is the lowly doorknob.  It’s shaped and sized for the hand to grab comfortably, and it’s placed at a height which makes for easy access to the hand.

Affordance ensures effective use.  The best designs are ones that can’t be misunderstood, and which don’t cause frustration.  The same applies to software design as to user interface design.

Doorknob

Is your design as good as this? 
(Don’t gold-plate it unless you’re asked to…)

Poor design is very expensive

Defining usable metaphors takes time and dedication to the task.  It takes time to model the entities in the application domain – entities the user will already be familiar with, and a requirement for creating a coherent model.  Often, the designers or engineers cave to schedule pressure and use an assortment of loosely coupled, functional designs:  the fields and listboxes and grids mentioned above.  These get the job done, but often at a high cost to UX, code clarity, extensibility, scalability, and maintainability.  

Individually and for certain tasks, these metaphors may be usable and may make sense.   But no system is an island any more, and complexity and other issues may pop up at system boundaries, interactions, and special cases.

As users, we have high expectations for software, and it’s the unexpected failures, the crashes, the lost documents, that lead us to silently loathe software.   Tell me:  who loves Microsoft Word?   Many use it, many respect it, but very few actually love it.

Conclusion

When designing software, ask what metaphors you’re offering to the user.  The key to usability is modeling your user interface after concepts the user understands fully.  As an added benefit, these concepts generally map one-to-one to objects or entities in your software designs and models, so you’re killing at least two birds with one stone.  There are many other benefits, all of which lead to better software in less time.  

Whatever it is you’re building, develop your metaphors fully, then make the software behave consistently with them.  Your users will thank you – and your clients will re-hire you.

Some great examples include:

  • Quicken’s check metaphor. As mentioned above.  More or less everybody could figure out how to use Quicken in 15 minutes.
  • Control panels. A good control panel or dashboard metaphor enables a user to understand what’s happening at a glance.  Everybody understands gauges, warning lights, and switches;  and almost everybody understands the basic semantics of red (problem/critical), yellow (warning), and green (ok).  
  • Print layout view.  Shows documents on the screen as they would look in printed form;  most modern word processors have this feature.
  • The Macintosh trash can icon.   Trash canContinues the metaphor of a real desktop; understood and loved by all.  (Yet to be understood:  why Apple’s OS designers violated this metaphor most rudely by requiring users to drag their disks into the trash can to eject them.  Tell me you didn’t think long and hard before you did that the first time.)

***

References / more reading

  • The Secret to Designing an Intuitive UX: Match the Mental Model to the Conceptual Model (UXMag.com, April 2010)
    This is what a metaphor enables…  Excerpt:
    “The secret to designing an intuitive user experience is making sure that the conceptual model of your product matches, as much as possible, the mental models of your users.”
  • The Design of Everyday Things (Donald Norman).   Excellent, fun-to-read treatment by one of the world’s foremost design authorities.  Learn about “affordance” and other tenets of good design, illustrated in everyday objects in the world around you.
  • useit.com (Jakob Nielsen).  A partner of Donald Norman (above) in the Nielsen-Norman Group and also a leading design expert.  Great articles and perspectives on usability.
  • Interface metaphor (Wikipedia).  Actually uses the example of files and folders, too. (I wrote this article before I read the Wiki entry.)
  • Tom Proulx (Wikipedia).  CO-founder of Intuit and passionate user interface designer who pioneered software usability testing.
  • Web Design Trends 2010: Real-Life Metaphors and CSS3 Adaptation(Smashing Magazine).