Rich Newman

February 26, 2008

Model-View-Presenter: Variations on the Basic Pattern (Introduction to CAB/SCSF Part 24)

Introduction

Part 23 of this series of articles described the basic Model-View-Presenter pattern (MVP).

This article examines the Model-View-Presenter pattern in more detail. It describes some variations on the basic pattern, and looks at the advantages and disadvantages of using the pattern.

Part 25 of this series of articles will examine how the Model-View-Controller pattern is implemented in the Smart Client Software Factory (SCSF).

Can the View Update Itself? Active View versus Passive View

The version of Model-View-Presenter described in part 23 has an ‘active View’. This means that the View can update itself directly from the Model (arrows C and D on the diagram in the article). As described in part 23, the View can also be updated by the Presenter.

An alternative to this is what Martin Fowler calls the ‘passive View’. Here the View cannot update itself directly from the Model. The only way the View can be updated is via the Presenter. This is the pattern that the Microsoft SCSF documentation describes as Model-View-Presenter.

Diagrammatically this looks as below. It’s identical to the diagram in part 23 except that there are no arrows between the Model and the View:

mvppassiveview.jpg

The passive View design leads to more code in the Presenter and more code in general as the View now has to expose everything that can be updated on its interface, and the Presenter has to be coded to update it appropriately. However, this is arguably a less complicated design than the original active View in part 23.

Does the View Update Automatically? Active Model-View-Presenter versus Passive Model-View-Presenter

As with Model-View-Controller we have a distinction between an ‘active’ and a ‘passive’ design overall (see the section ‘Active and Passive MVC’ in part 22). Model-View-Presenter as described above in part 23 is ‘active’ Model-View-Presenter. This means that if the Model changes all Views will be updated automatically via the eventing mechanism. These events may be sunk in the Presenter or the View.

It is also possible to set up ‘passive’ Model-View-Presenter. This is a slightly simpler pattern where the Model does not raise an event when it changes. This means the View is not updated ‘automatically’. Instead the View is updated when the user next requests it (by pressing a ‘Refresh’ button for instance). At this time either the View or the Presenter will go to the Model to get the new data.

Advantages of Model-View-Presenter

As with Model-View-Controller, Model-View-Presenter has the advantage that it clarifies the structure of our user interface code and can make it easier to maintain. Not only do we have our data taken out of the View and put into the Model, but also almost all complex screen logic will now reside in the Presenter.

This solves the problems with more traditional user interface designs as described in the last few articles. However, it comes at the cost of some complexity.

Since we now have almost no code in our View apart from screen drawing code Model-View-Presenter also makes it theoretically much easier to replace user interface components (user controls, whole screens, or even the whole user interface (Windows Forms to WPF for example)).

In addition unit testing the user interface becomes much easier as we can test the logic by just testing the Presenter. However see part 23 for some comments on whether this is strictly necessary.

Disadvantages of Model-View-Presenter

The disadvantages of Model-View-Presenter are similar to the disadvantages of Model-View-Controller as described in part 22:

  • The pattern is complex and may be unnecessary for simple screens.
  • The pattern is one more thing to learn for busy developers: there’s some overhead.
  • It can be hard to debug events being fired in active Model-View-Presenter.
  • The ‘Passive View’ version of Model-View-Presenter can lead to a certain amount of boilerplate code having to be written to get the interface into the View to work.

My personal view is that even if you think this is a useful pattern (and it is) you shouldn’t use it indiscriminately on every screen in your application. You should use it where you have reasonably complex logic which will benefit from splitting the user interface classes in this way.

User Events and View Logic Combined in the Presenter

One thing that seems a bit odd with Model-View-Presenter is that we have factored both the responses to user input events and what I’m calling the ‘complex view logic’ into our Presenter. At first glance these seem to be slightly different things: perhaps we should have separate classes for each? Perhaps we need a Presenter and a Controller?

One reason for not doing this is that our user interface is getting very complicated if we have both Presenter and Controller.

Also, in the passive version of Model-View-Presenter we may want the user event itself to call the complex view logic and to directly update the View. This means that the code to handle the user event also needs to contain the view logic. It can’t do this if we have separate classes for the two pieces of functionality. In this case it makes more sense if we only have one class.

However, splitting the Presenter into two classes may be a valid pattern in active Model-View-Presenter. Here the Model will be updated in response to a user event by the Presenter. The Model will then raise an event to the Presenters telling them to update the View for complex view logic. The user event and complex view logic are thus separate in the Presenter and could be split into separate classes. We would probably only want to do this in very complex screens.

Model-View-Controller and Model-View-Presenter Confusion

As Martin Fowler points out, there’s a lot of confusion over what Model-View-Controller is. As already discussed, this arises because it doesn’t really apply to modern user interface programming languages in its purest Smalltalk form.

Equally there seems to be a lot of confusion over what Model-View-Presenter is. Martin Fowler currently calls the basic MVP pattern that I describe in part 23 ‘Supervising Controller’. He calls the amended version presented in this article ‘Passive View’ (as does this article).

I’m not quite sure why Mr Fowler calls the basic Model-View-Presenter pattern ‘Supervising Controller’ and not ‘Supervising Presenter’. It seems to me that the key difference between Model-View-Controller and Model-View-Presenter is that the Presenter in Model-View-Presenter can update the View directly. This is not permitted in Model-View-Controller; here the View updates itself from the Model. In the ‘Supervising Controller’ the Presenter/Controller can update the View directly.

Having said that I’m not sure that Mr Fowler would recognize the pattern described in part 22 as Model-View-Controller: this is closer to Model-View-Presenter as he describes it. As I mention in part 22 the pattern described is not ‘pure’ Model-View-Controller because the user events are initially sunk in the View (which is normal with modern UI widgets) and because there’s only one Controller and View per screen, rather than one per widget as in pure Model-View-Controller.

Finally note that I have adopted the ‘Passive View’ nomenclature in this article. However personally I think calling this pattern ‘Passive View’ adds to the confusion surrounding Model-View-Presenter. We already have the concept of active/passive Model-View-Controller and Model-View-Presenter as a whole, ‘active’ being the case where all Views get updated automatically on a change in the Model, ‘passive’ being where they have to update themselves. This is easily confused with an active/passive View distinction. Here an ‘active’ View is one that can update itself from the Model, whether automatically or not.

Conclusion

We have now covered quite a lot of the theory behind both Model-View-Controller and Model-View-Presenter.

Part 25 of this series of articles will show how we can use Model-View-Presenter in the CAB/SCSF using an SCSF Guidance Automation Pattern.

References

The two flavours of Model-View-Presenter described by Martin Fowler
http://www.martinfowler.com/eaaDev/PassiveScreen.html (‘Passive View’ in fact)
http://www.martinfowler.com/eaaDev/SupervisingPresenter.html (‘Supervising Controller’ in fact)

Martin Fowler overview of GUI Architectures, including Model-View-Controller and Model-View-Presenter
http://www.martinfowler.com/eaaDev/uiArchs.html

Good explanation of Model-View-Presenter, Passive View and Supervising Controller on CodePlex
http://www.codeplex.com/websf/Wiki/View.aspx?title=ModelViewPresenterPatternDescription&referringTitle=MVPDocumentation

MSDN Article with code example (although the article is a little confusing)
http://msdn.microsoft.com/msdnmag/issues/06/08/DesignPatterns/

See also the page in the Smart Client Software Factory documentation on Model-View-Presenter
http://www.codeplex.com/smartclient/Release/ProjectReleases.aspx?ReleaseId=5027

February 25, 2008

Model-View-Presenter: Why We Need It and the Basic Pattern (Introduction to CAB/SCSF Part 23)

Introduction

Part 22 of this series of articles looked at the Model-View-Controller pattern and discussed how it is one way of structuring a user interface to avoid having too much code behind a screen.

This article will examine some of the shortcomings of Model-View-Controller, and describe an alternative, which is Model-View-Presenter.

Part 24 of this series of articles will then briefly examine some variations on the basic Model-View-Presenter pattern described here, and look at the advantages and disadvantages of the pattern.

Part 25 of this series of articles will look at the support that CAB/SCSF gives us for the Model-View-Presenter pattern.

Model-View-Controller Problems

There are a couple of user interface scenarios that are difficult to handle with the Model-View-Controller pattern. The first of these is the one that is most widely cited as a problem with Model-View-Controller, but in my opinion the second is the more difficult case to deal with, in spite of the fact that it’s hardly an unusual scenario:

1. Elements of our screen display depend on complex business logic

The canonical example here is coloring the background of a field in varying colors depending on the output from some business rule.

For example suppose we are showing daily sales figures for a business. We might want to color the background of a sales figure green if that figure is more than 10% above the average daily sales figure for the quarter, and color it red if it’s more than 15% below the average. Otherwise we leave the background white.

Model-View-Controller struggles with this scenario. Clearly it involves calculations involving business logic (averaging the sales figures for the quarter). In the Model-View-Controller pattern the business logic should go in the Model class. However, the only place we can sensibly put the coloring logic is in the View when it refreshes itself. We’ll come back to this below.

Note that we want to be able to enter the daily sales figure and have the background color change appropriately depending on the new value.

2. Elements of our screen display depend on what the user has selected in other screen components in a complex way

This could be as simple as a Save button being enabled only if the user has actually changed something on the screen (and being disabled again if the user changes the screen back to its original values).

Again the only place we can logically put this sort of logic in the Model-View-Controller pattern is in the View when it refreshes itself.

Whilst these problems are slightly different they can both be thought of as complex view logic surrounding the state of the user interface.

Why is Putting View Logic in the View a Problem?

In both of the examples above there probably isn’t all that much code relating to our view logic, and maybe putting it in the View in a Model-View-Controller pattern will be fine. However, with complicated screens this ‘view logic’ can run to many hundreds of lines of code. We don’t really want this code in our View, which we want to just be simple screen drawing code. Part of the idea of splitting out the View, after all, is that it becomes so simple we can easily replace it if we want to change our screen technology.

Another problem with having this logic in the View is that the event model may get quite complex. In my example it’s possible that a change in a sales figure that we’re not actually displaying could affect the background color of the textbox. Remember that we are comparing the textbox contents to the average daily sales. If the average daily sales change sufficiently we may need to raise an event to force a color change.

There’s another reason why developers prefer to get this ‘view logic’ out of the actual View class. It can be hard to automatically unit test a View class. Screen widgets often don’t lend themselves to unit testing. If the view logic is in another class it may be easier to unit test it.

Aside on Unit Testing in User Interfaces

I think the difficulties of unit testing user interfaces in Microsoft world are hugely exaggerated. Most Microsoft controls will let you do programmatically almost anything you can do with a mouse and keyboard. So, for example, we have a PerformClick method on a button, and settable SelectedIndex and SelectedItem properties on a ListBox. We can instantiate our screen in the test and interact with it programmatically in the same way we would if we were clicking on things. We have extensive unit tests that work this way in our current project.

It’s true that interactions between controls can be difficult to test (e.g. drag-drop operations). Also third-party (non-Microsoft) controls often don’t expose mouse and keyboard actions in the same way. However, in general you can usually unit test a user interface fairly extensively without recourse to restructuring your code as outlined in this article.

The Presenter in Model-View-Presenter

The first thing to understand about Model-View-Presenter is that it is very similar to Model-View-Controller, only with the Controller replaced with a Presenter (predictably).

The idea of the Presenter is that it can update the View directly. This isn’t permitted for a Controller in Model-View-Controller. This means we can put our complex ‘view logic’ described above into the Presenter and take it out of the View. Clearly we couldn’t do this with the Controller in Model-View-Controller since it had no easy way of updating the View with the results of the view logic: the View updated itself from the Model and the Controller was not involved.

Note that the Presenter, as with the Controller in Model-View-Controller, handles user events raised from the View as well. This means the View only contains screen drawing logic, which is what we want.

So a Presenter is able to ‘present’ data: it can directly update the View. On the other hand a Controller only controls: it takes user input and updates the Model as appropriate. Note that the Presenter is doing some controlling as well since it handles user events.

Diagram of Model-View-Presenter

Diagrammatically this looks as below:

mvp.jpg

As you can see, we again have three classes that interact. As with Model-View-Controller the Model class contains the data to be displayed, and the View class contains the code that actually draws the screen. We have already discussed the Presenter.

As with Model-View-Controller we can have multiple Presenter/View pairs of classes interacting with the same Model (with a change entered on one screen updating other screens showing the same data).

Class Interaction (active Model-View-Presenter with an active View)

When a user interacts with the View an event will be raised. This will be passed immediately to the Presenter (A). The Presenter will update the Model as appropriate (B): it may go back to the View to get the data it needs (F). The Model may at this stage raise an event that gets sunk in the View (C), leading to the View updating itself from the Model (D).

So far everything is the same as in active Model-View-Controller (except with the Controller replaced with the Presenter).

The difference is that when the Model is updated by the Presenter it may raise an event that also gets sunk back in the Presenter itself (E). The Presenter may then apply the complex view logic to work out what needs to be displayed before updating the View (F).

So in this version of Model-View-Presenter the View can update itself directly from the Model in simple cases where there is no view logic. When some view logic is needed the Presenter intervenes. It handles that logic and updates the View directly.

Interface on the View (F)

Another point to note here is that the Presenter accesses and updates the View through a clearly-defined interface on the View (F in the diagram). This has two effects. Firstly we can replace the View more easily with another screen technology since we know exactly what methods need to be exposed (those in the interface). Secondly this makes automated unit testing simpler. We can test the Presenter without needing screen elements directly by mocking the interface on the View in another class.

Conclusion

This article has described a basic Model-View-Presenter pattern and contrasted it with Model-View-Controller. It has examined why we need a different pattern to Model-View-Controller.

Part 24 of this series of articles will examine some variations on the Model-View-Presenter pattern described here, including the one in the Microsoft documentation for the SCSF. It will also discuss some of Martin Fowler’s user interface patterns that are relevant. References to articles for part 23 and part 24 will be given at the end of part 24.

November 16, 2007

More Detail on Workspaces and SmartParts (Introduction to the CAB/SCSF Part 16)

Filed under: .net, c#, CAB, Composite Application Block, SmartPart, User Interface Design, Workspace — richnewman @ 4:03 pm

Introduction

Part 15 of this series of articles explained SmartParts in the CAB, and gave a very brief introduction to Workspaces. This article will continue with the same topics. In particular we will look in more detail at Workspaces.

Workspaces Recap

Part 15 explained the SmartParts can be most easily thought of as user controls or views in a composite application block application.

Part 15 also explained that Workspaces are just controls that allow other controls (SmartParts) to be laid out within them, and differ from other container controls in that they interact with other objects in the CAB in a predefined way. In particular there is a Workspaces collection on any WorkItem, and they have a Show method that shows a SmartPart.

User Interface Design for Business Applications

In an earlier blog posting on user interface design I discussed some of the possible user interface designs for applications that have to display multiple different screens of data. A common design for these applications is to have a tabbed client area for the screens, together with a tree-based window manager of some kind. An alternative is an Outlook-style interface, again possibly with a tree window manager, but dispensing with tabs at the top of the screen. Clearly both of these designs are very similar: we click on a tab or double-click in a tree and our screen gets displayed in a predefined part of the screen.

One thing to notice with both of these designs is that after we have displayed a client screen for the first time we won’t usually close it again. When other screens are displayed our first screen will stay in memory. It will retain the state it was displaying the last time the user interacted with it. When the user requests to see the screen again it will just be brought to the front.

So we have a collection of objects (our screens) with persistent state whilst the application is running. We may create all of these screens at start-up. However more usually we’ll create a screen the first time the user requests it, and then redisplay it the second time it is requested (a sort of lazy initialization). Note that at any given time many of the screens in the collection may not actually be displayed at all.

Building User Interfaces for Business Applications

Of course it is easy enough to create an application of this kind using Windows Forms standard controls. However, there’s some infrastructure code that we are going to have to write. We need:

  • some means of caching our screens collection
  • a way of allowing new screens to be added to the screens collection
  • a method of displaying a screen when it is requested for the first time
  • a method of redisplaying the appropriate screen in response to the appropriate request

We’ll also want to make sure we control the scope of our screens carefully so that they can’t be accessed from anywhere in the code. As we all know, global singletons (or global variables of any kind) are a bad thing.

The good news is that Workspaces and SmartParts do all this for us. What’s more they do it in a very simple way.

Workspaces – the IWorkspace Interface

All Workspaces implement the IWorkspace interface. This is the interface we are meant to use to interact with our Workspaces: usually we don’t need any more functionality than this interface provides as we shall see.

The IWorkspace interface has a number of useful methods. In general these behave as explained below, although each type of Workspace is free to implement them in its own way:

void Show(object smartPart)

When this method is called, if the SmartPart passed as a parameter has not previously been shown in this Workspace it will be loaded and then activated. If it has already been shown and not been closed (i.e. if it is in the Workspace’s SmartParts collection) it will just be activated. Usually ‘activated’ means brought to the front and made into the ActiveSmartPart.

void Activate(object smartPart)

If the object is in the Workspace’s SmartParts collection it will be activated as described above. If it’s not in that collection then an ArgumentException will be thrown.

void Hide(object smartPart)

Hides the SmartPart (sends it to the back usually), but leaves it in the Workspace’s SmartParts collection. The next control in the Workspace will usually be activated (made into the ActiveSmartPart). What ‘next’ means here varies by Workspace.

void Close(object smartPart)

Hides the SmartPart and also removes it from the SmartParts collection. The next control in the Workspace will usually be activated.

IWorkspace also has a property ActiveSmartPart, which returns the active SmartPart if there is one. As discussed in part 15 Workspaces have a SmartParts collection, and the IWorkspace interface has a SmartParts property that lets us access this (it returns a ReadOnlyCollection<object>).

IWorkspace also has events SmartPartActivated and SmartPartClosing. You can probably guess when these get fired.

There are also some methods to deal with SmartPartInfo on IWorkspace. I’ll discuss SmartPartInfo below.

Workspaces – Aside on how the Supporting Classes Work

The core functionality of IWorkspace is encapsulated in a class called, appropriately, Workspace. This is an abstract base class that all Workspaces are expected to inherit from. It implements IWorkspace so the individual Workspace classes don’t have to (since they inherit the interface from Workspace).

The base class gives basic implementations of the members of IWorkspace, and also handles things like caching the active smart part, tracking the SmartParts collection, and raising the right events at the right time.
Whilst the way the supporting classes work is quite interesting, you don’t need to know it in any detail to use the Workspace classes. The exception to this is if you want to write your own custom Workspace class, in which case you will need to get to grips with them in more detail. Writing your own custom Workspaces is beyond the scope of these articles for now.

Further Aside on Multiple Inheritance in C#

The Workspace classes also demonstrate a method of achieving a kind of multiple inheritance in C#. This is done by composition, using a class called WorkspaceComposer and an interface called IComposableWorkspace. It’s needed because certain Workspace classes (e.g. TabWorkspace) already inherit a Control class to give their basic functionality (in the case of TabWorkspace this is TabControl). As we know, in .NET a class can’t directly inherit more than one other class.

It is not my intention in these articles to actually discuss the underlying code in the Composite Application Block in any detail. The aim of these articles is to let you use the CAB as a black box component. But the WorkspaceComposer is particularly interesting since it shows us a pattern for achieving multiple inheritance (albeit messily) in C#. If you are interested the code is in the Microsoft.Practice.CompositeUI.SmartParts namespace in the Microsoft.Practices.CompositeUI component.

SmartPartInfo

As we have seen the normal Show method on the IWorkspace interface only lets you pass the SmartPart you want to show as a parameter. There may be other information that the CAB framework will need to know to show your SmartPart correctly. For example, in a TabWorkspace you need to provide the text for a new tab somehow. In a ZoneWorkspace you need to tell the CAB which particular zone the SmartPart will be displayed in.

This problem is solved by passing an additional object to the Show method:

void Show(object smartPart, ISmartPartInfo smartPartInfo)

This additional object implements the interface ISmartPartInfo, which has Title and Description properties. It’s the Title property that’s used to set the tab page title in the TabWorkspace.

The smartPartInfo object can contain any additional information we require. For example, for ZoneWorkspaces it contains the name of the zone in which the SmartPart will be displayed.

The IWorkspace interface also has a method to directly apply the information in a SmartPartInfo object to a SmartPart that has already been displayed:

void ApplySmartPartInfo(object smartPart, ISmartPartInfo smartPartInfo)

In a ZoneWorkspace this can be used to change the zone where a SmartPart is shown in, for example. The next article in this series will give some examples of this.

Conclusion

This article has discussed some of the theory behind Workspaces, and shown the basic interfaces. Part 17 in this series of articles will discuss the various types of Workspace that are available in the CAB, and give some code examples of how to use them.

October 26, 2007

User Interface Design for Business Applications

Introduction

This article is going to give a quick tour of the various high-level user interface designs for business applications that need to display multiple windows. It will discuss multiple document interface (MDI), single document interface (SDI) and other paradigms for handling multiple windows. The article will illustrate these concepts by looking at the user interfaces in Microsoft’s various desktop applications, both good and bad.

This article will be referred to by my series of articles on the CAB and SCSF but is not part of that series.

Business Applications

Before we start we need to consider what we mean by business applications. For the purposes of this discussion I mean applications that have some or all of the following characteristics:

  • display of data, often in grid form
  • some means of interrogating the data (querying, sorting, filtering, drilling down)
  • calculations based on the data, comparison of data (reconciliations), and display of results
  • some kind of data entry and persistence
  • data updates from other applications, maybe in real time
  • exports to Excel or paper or other formats
  • feeds to other systems

I work in banking, and would say that all the applications we build fall into this category, with the possible exception of internet-based applications for clients. Such applications may or may not be classic online transaction processing systems (OLTP).

In general these applications do not need to catch the user’s attention in competition with other applications, unlike internet-based consumer applications. As a result they largely will not use multimedia effects (video, animation, graphics). They are intended to be functional above all else.

Having said that such applications often do need to have a rich and responsive user experience. It is still hard to do that with HTML-based interfaces, even with the advent of Ajax. Often these applications are solely for internal use within an organization, where there will be a consistent desktop computer base with appropriate security. As a result deployment of smart client applications becomes possible and these applications are often built as smart clients.

High-level Design of User Interfaces for Business Applications

In this article I’m going to illustrate the various possible high-level designs for business applications using Microsoft’s own selection of applications. Whilst these are not really ‘business applications’ in the sense I have described above, they do illustrate the possible designs.

The difficulty that we are trying to address here is that our business applications will typically need to show many different screens with many different types of data in them. We may want to show more than one screen simultaneously, and may even allow data to be dragged between screens (although it’s arguable that this is one user interface paradigm that should not be used). There usually needs to be some central way of managing the various screens (a window manager), as well as some means of transitioning between them. Above all it’s critical that the user can easily navigate the system, and can use it in a flexible way that fits with their requirements.

Multiple Document Interface (MDI)

The ‘classic’ Multiple Document Interface (MDI) design has been with us for many years now, and at one stage was a very common way of handling the user interface problems described above.

A Multiple Document Interface application has a main ‘shell’ MDI window with just a menu bar and possibly a toolbar. The user can load individual screens from these bars, and the screens will just ‘float’ within the window.

Typically these applications have a ‘Window’ menu option, with ‘Tile’ and ‘Cascade’ options that rearrange all open windows. We also usually have a list of open windows on the ‘Window’ menu to allow us to find an individual screen.

There are several applications of this sort still around, even in the Microsoft stable:

access20032.jpg

entmgr2.jpg

One advantage of this sort of user interface design for enterprise applications is that it can be very easy to develop. Every screen is a form, there’s an easy way of creating one directly from a menu click, and window management is simple. If you cache your data on the client and use a simple model-view-controller pattern you can keep the data on the screens up-to-date relatively easily as well.

Of course the major disadvantage is that the user experience isn’t that good. It’s easy to ‘lose’ windows, and as you can see even in my simple screenshots above, windows overlap and what you want to see is often hidden.

It’s for the reasons outlined above that Microsoft has been phasing out this sort of interface from its own products.

Single Document Interface (SDI)

In a Single Document Interface (SDI) application there is only one window in each instance of the application. If you want a second window you start a second complete instance of the application. Switching between windows happens at the operating system level when you switch between applications. In Microsoft Windows this means you that you use the Taskbar to select a different window, as all windows will have an icon in the taskbar.

Microsoft uses this paradigm for Microsoft Word. If you open two documents in Word you get two separate instances of the application:

word2007a2.jpg

This is the default behaviour. It is possible to use Word as a proper ‘classic’ MDI application by changing one if its many options settings: if you click the Office button (top left), click Word Options, go to the Advanced tab and scroll down to the Display section there is a checkbox labelled ‘Show all windows in the Taskbar’. If you clear this Word will have an MDI interface:

word2007b2.jpg

Excel behaves strangely with regard to this. It has the same menu option, but its default behaviour with the ‘Show all windows in the Taskbar’ checkbox checked is different. Here if you open two Excel documents they are still MDI (i.e. they appear in the same window), although they do have two window icons in the Taskbar:
excel2007a2.jpg

If you clear the checkbox all that happens is that you get one icon in the Taskbar instead of two (i.e. there’s almost no difference):

excel2007b2.jpg

SDI does make some sense for Word and Excel where you will typically only have a few spreadsheets or word processing documents open at a time and may want a way to navigate quickly between them. The operating system Taskbar is ideal for this.

However, this sort of interface is usually not applicable to the complex business applications discussed earlier in the article. These applications will have multiple screens with different data being shown, and trying to manage all of those and their interaction through the Taskbar would be extremely difficult.

For this reason it is rare for business applications to be designed using SDI.

Basic Tabbed Document Interfaces (‘TDI’) – Browsers

Many modern desktop applications now use tabbed document interfaces of some kind. Rather than having multiple floating windows that are difficult to control (MDI), or each window in a separate instance of the application (SDI) we allow multiple windows but insist that they are arranged as tabs. This is dubbed ‘TDI’ for ‘Tabbed Document Interface’.

For example, almost all browsers now support different pages being shown on different tabs:

firefox2.jpg

Even Internet Explorer now supports this in version 7, having held out as an SDI application in versions up to that point.

Disadvantages of Basic Tabbed Document Interfaces

There are two major disadvantages of pure tabbed interfaces for business applications:

  1. An obvious disadvantage of this design in its purest form is that it isn’t possible to display two windows alongside each other, and thus is difficult to arrange for drag and drop between them. Browsers typically get around this problem by allowing a new document to be shown in a new tab or a new window, thus creating a mixed TDI/SDI model. This is probably not an appropriate solution for business applications.
  2. Another disadvantage for the kind of business applications we are talking about here is that we may need to support a very large number of screens (windows) being open simultaneously. A simple tabbed arrangement can make it very difficult for a user to find the window they are after. On our current application we had to abandon all use of tabs for this reason (although we were also using a window manager, see below).

Montage Tabbed Interfaces – ‘IDE-style’ interfaces

Microsoft has recently moved some of its old ‘classic’ MDI applications into a tabbed format, but with surrounding property and window management panes:

access20072.jpg

sqlmgtstudioa2.jpg

Note that both of the screenshots above are of updated versions of the MDI applications we saw in the ‘classic’ MDI section above. They have the advantage over those older interfaces that we are less likely to ‘lose’ a window and usually won’t need to use a Window menu to navigate. The layout is tidier too.

Note also that SQL Server Management Studio solves problem 1 mentioned above in the section ‘Disadvantages of Basic Tabbed Document Interfaces’ by allowing the central tabbed area to be split horizontally or vertically into multiple ‘tab groups’:

sqlmgtstudiob2.jpg


Tree-Based Window Managers

These applications also show for the first time the now common approach for doing window management in modern user interfaces. We have a tree view in a pane to either the right or left of our main document window. This tree organizes our documents in a logical hierarchy, meaning we can find the document we are after fairly easily. Clicking or double-clicking in the tree will open the document or bring it to the front if it is already open. This is a big step forward from a Window menu that just listed open documents in a random order. However, the old MDI version of SQL Server Enterprise Manager also had a tree-based window manager, so it’s not a new idea.

These window managers mitigate problem 2 mentioned above in the section ‘Disadvantages of Basic Tabbed Document Interfaces’: we still have the problem that we may have a very large number of tabs open, but at least we have a tree that will let us go to the one we need.

Integrated Development Environment Interfaces

Of course both of the ‘Montage Tabbed Document Interface’ applications shown above resemble the older integrated development environment interfaces all developers are now familiar with from such applications as Visual Studio and Eclipse:

visstudio2.jpg

As we all know, this user interface is highly customizable. We can display tabbed documents alongside each other (as shown above) and drag between them. We can ‘tear off’ any of the surrounding panes and have them float free of the main window. We can easily then dock them to any part of the interface.

Again we have a tree-based window manager in the Solution Explorer pane that allows us to go directly to a tab if we have too many open to easily find the one we need (and we all know that can be a problem).

Disadvantages of the Integrated Development Environment User Interface

This kind of interface is great for an integrated development environment; it’s hard to find a developer who doesn’t like Eclipse or Visual Studio (at least now it doesn’t fall over every few minutes). However a user interface this complex may not be appropriate for a business application. The tear-off property windows in Visual Studio in particular are a nice idea, but lead to the old problem of you not necessarily being able to find your window, particularly if you have multiple screens. I doubt many developers actually use this feature: I certainly don’t.

Users of business applications usually don’t need to be able to highly customize the user interface. Indeed allowing them to do so can cause problems if a complex application is used in ways the developers are not expecting. In general it can be better to retain a little more control. It’s certainly harder to program (and hence more expensive to maintain) an application that allows multiple panes to be ‘torn off’ from the main application and kept synchronized with the application.

Montage Interfaces without Tabs – Outlook-style Interfaces

For some of the reasons cited above Outlook-style interfaces are currently very popular for business applications:

outlooka2.jpg

Even if you use this product every day it’s worth thinking about what’s good and bad about the interface.

We have a tree-based window manager, which in the corporate environment is often used to manage quite extensive trees of documents. Emails can be displayed in the main window, as shown, or can be in their own window with a separate icon in the Taskbar, which is useful to be able to find them when you are writing a new one whilst still checking new mail.

There are no tabs here either, other than the collapsible sections themselves, which clearly aren’t quite the same thing as allowing multiple documents to be opened in a tabbed view.

The pane to the left hand side has collapsible sections of course, allowing us to select completely different areas of functionality of the application. This is an attractive way of doing things if we are writing complex business applications. Of course it’s particularly attractive if we are writing a composite (CAB) application as each module can be on a different collapsible section.

outlookb2.jpg

What’s interesting about the screenshot above is that we don’t need a tree window manager for our notes, so Microsoft have used the space to put in a simple set of radio buttons to allow us to change the view. This really isn’t a great use of space, and this is one drawback of this design: for simple areas of functionality you may not need a window manager. You can find yourself trying to invent something useful to put in the Outlook pane when you don’t really need it.

However overall this isn’t a bad starting place for a design for a business application. It’s simple but quite powerful. Many of the tools vendors have realized this and ship components that support such an interface. In fact most of the major vendors seem to have fully mocked up versions of Outlook running using their tools as demonstrations.

Conclusion

This article has looked at some possible high level interface designs for business applications that need to display multiple windows of data, and considered some of the pros and cons of each. For a composite application an Outlook-style interface can be a good starting point.

References

Wikipedia on:
Multiple Document Interfaces
Single Document Interfaces
Tabbed Document Interfaces

Microsoft Design Specifications and Guidelines – Window Management

The Shocking Blue Green Theme. Blog at WordPress.com.

Follow

Get every new post delivered to your Inbox.

Join 81 other followers