Monthly Archive for November, 2008

Sorting Collections without implementing IComparable

This is an old but a goodie from Albert over on his blog. It uses delegates to allow inline sorting of Generic collections based on the specific types without having implemented IComparable in the type being sorted.

jQuery Intellisense in VS2008

Title says it all really.

Innovator’s Dilemma

Luis over on Planet Gnome has an interesting article about an interesting book, The Innovator’s Dilemma.

Looks like I’ve found my next train-ride distraction

Virtual Earth and iPhone goodness

As seen on the VE blog.

A word of warning though, to get this to work you have to do un-godly things in this day and age like building and parsing your own SOAP requests and responses as well as regenerating the tile pyramid. This is mainly because it’s using the VE web service API. More info on the jump.

The Search System Part II – Search Abstraction Concepts

Posts in Series: Application Search Systems

  1. On Application Dev and Common Patterns – The Search System Part I
  2. The Search System Part II – Search Abstraction Concepts

So I lied, Part II isn’t going to be about data access, but rather abstraction concepts. So lets just dive into it.

From a UI perspective when a user is using a search system they normally interact with two distinct screens. The search criteria screen, where the user enters the values for the criteria with which to conduct the search, and the search results screen, where the actual end results of the search are displayed to the user.With that in mind, lets move on to the main point of this article.

When trying to abstract the search function of any non-trivial (aka enterprise) application there are a number of concepts that you need to be aware of. I’ll briefly list them here and then delve into them in detail:

  1. Search Complexity
  2. Search Mode (what entity you are actually searching by)
  3. Result Mode (what entity you are searching for)
  4. Search Display (how you want the display of the result to be customised)
  5. Search Action (what you want the result of the search to do)
  6. Search Restriction (aka UI metaphor re-use)

Search Complexity

No matter the complexity of the system it’s driving, if you care about your users you should always consider search complexity first. This is essentially the realisation that (queue random fake statistic) 90% of the time your users will search for the same type of entity, by the same search criteria (with different values obviously).

Realising this enables us to address this from get-go. So how do we address this? Simple, we design our search system abstraction to handle two levels of search complexity, Simple and Advanced. Always present the Simple search UI to users on a cold search query. This way we optimise the user experience for this majority run operation, but also allow the user to select the Advanced Search dialog/tab (whatever UI metaphor you are using) in order to expand their available search criteria.

The Simple search level should present the user with 3-5 search criteria that will be most frequently used to recall (physically) and hence search for the particular record. In heavily financial systems don’t be afraid to allow one of these fields to actually be the numerical ID of entity being searched for.

The Advanced search level should allow the user to search for entities in the given system module by any conceivably useful search criteria. We’ll also look at how we can leverage the Advanced search for more re-use with related items later on when we discuss Data Access and UI.

Depending on the user base and the number of levels in the entity hierarchy for the given application module it sometimes helps to introduce a third search complexity, ID Search. This basically does what it says, allows users to load a record (or set of related child entity records) based on a given entity ID.

Search Mode

Search mode defines what you are searching by (not what you are searching for).

Consider this example; The Customers Module in a CRM system. If you are searching for customers using a Company name then it’s pretty straight forward. But if you are searching for customers using a contact’s First or Last Name then you are actually searching by the person entity, not the company/customer entity.

Your search system will need to interrogate the supplied search criteria (all of which are of-course optional) to determine what type of entity you are actually searching by. For Advanced search it gets even more complex since you can even be searching by multiple entities.

Keep in mind that you sometimes also want your search mode to override the supplied result mode. Search for a customer by contact name, and then only seeing company records (no person details) in the result set can be quite disorienting for a user.

Result Mode

This is how you want to see the result. Going back to our example, the customers module of a CRM system there are potentially 3 search modes that come to mind; company/customer, person and address (since both persons and companies can have attached addresses).

The point to keep in mind here is that you always need to set the result mode based on the context in which the customer was performing their search. Just because someone has entered in address details for a customer search doesn’t mean they want to see addresses, they want to see customers.

Search Display

Which leads us into search display. Most times each result mode will have it’s own set of columns to be returned in a search. But you need to build in flexibility to handle the differing combinations of Search and Results Mode.

Going back to the example, the default columns returned when searching for a customer/company, by a company name would be something like: Company Name (or short name for display purposes), contact number (front desk), Suburb and maybe even the customer ID. However when the user searches for companies by a given contact’s first name you also need to include details about that person in the customer’s result list, this is easily accommodated by including a contact field (eg. concatenation of the person’s salutation, first name and last name).

Search Action

Going back to the theme of Metaphor re-use the search action is the abstraction that facilitates this in our system. The result of a search can most often be classified into 3 actions:

  1. Loading a new entity in the current system module, as in when driven by the search item in the modules main menu.
  2. Selecting the record identifier for use in a field in the details screen of another module (think selecting a primary contact in the main details screen of a company record).
  3. Adding a new record for use in either of the above 2 actions. Though not techincally a search, this is essentially adding a new step in the user’s pathway to the end result, simply adding that record so that it can be selected in either of the two options.

Search Restriction

When using the search system for the second action above an interesting issue crops up.

When you use the search system as an intermediate step in selecting a given record for the details screen of another entity’s module you can’t actually allow the user to change all the search criteria, but rather simply refine the result set down.

For example, when selecting the primary contact of a given customer/company you should be presented with a search results screen of all the contacts attached to that customer record, and no one else. In this case the search results system is loaded, and prepopulated with the search criteria of the current customer (customer ID usually works well here) and the results screen is presented without allowing the user to go back to the search criteria screen. The user should be allowed to refine their result set but this can be done more simply at the presentation layer of the application (to be discussed in the UI article).

On Application Dev and Common Patterns – The Search System Part I

Posts in Series: Application Search Systems

  1. On Application Dev and Common Patterns – The Search System Part I
  2. The Search System Part II – Search Abstraction Concepts

I’ve been building “enterprise web applications” for quite some time now and seen a number of recurring process/usage patterns evolve in my designs that I thought I might talk about.

Today’s pattern is the enterprise application Search System. Most application’s tend to have a global nav that’s broken up into a whole bunch of modules or entities. These are the base level menu items (for clarity I’ll use module here-in) of the application. Those modules are often directly tied to a fundamental business process, or a real life entity being operated on by a fundamental business process. Think the Customer module in a CRM (Client Relationship Management) system.

Then bellow these base level menu items you normally have a number of common operations; search, add, edit and show related. That is, search for or about a module’s primary entity, add a new entity in this module, edit an existing entity (involves engaging the search process), and show me related info to this module’s entity (another form of search), respectively.

Notice how the search system seems to be integral to second level menu items of all your system’s main modules. That there is an indicator that this thing called search is probably going to be an area to focus on when it comes to re-usibility, flexibility and agility of design and execution. Enter the Search System Pattern.

If you take this another step further, in most modules you often have a multiplicity relationship between two entities. In terms of a database, think about a foreign-key relationship beteen two entities.

In terms of an actual example, think the designated Customer of an Opportunity in a CRM system. For a given Opportunity you need to select a Customer that the opportunity is for, if both opportunity and customer are entities in the system then we have another prime usage for the Search System pattern.

From a usability perspective the Customer field on the Opportunity module’s detail screen should allow the user to do two of the 4 tasks in the main system nav; search for a customer or add one. Introducing yet another usability metaphor here is a mistake. The user’s already had to learn how to search for and sift through a list of results for Customer in the main nav. Why not re-use that metaphor again here when selecting the customer for this opportunity?

Not into the low level detail (that’s for a later posting) this is the essence of the Search System Pattern; a series of design decisions, architectural contracts and application interfaces that mean the user will be presented with the same metaphor anytime they need to select, add or find a related entity for a given operation.

It’s worth noting though, that in applications a “Search”, by it’s very definition, is very specific task. So you could waste many man hours trying to generalise and abstract the Search system resulting in an over-engineered, hard to understand system. You need to achieve a balance between delivering the specificity of an application search and doing it in a way that does re-use common code and user metaphors. In this respect, the Search System Pattern, is more than just a design pattern as it also involves usability aspects and metaphors as well as the underlying system design.

In the next article… Designing the Search System’s Data Access Layer