Achieving Usability Through Software Architecture
6 Architectural Patterns and Categorization
This section presents an architectural pattern for each of the general usability scenarios and places each scenario into the software engineering hierarchy. These patterns do not represent the only possibility for implementing the scenarios. Rather, they present one pattern and discuss many of the issues associated with its implementation. Thus, an architect may find these patterns useful even if they are not adopted.
6.1 Aggregating Data
A user may want to perform one or more actions on more than one object. For example, an Adobe® Illustrator® user may want to enlarge many lines in a drawing. It could become tedious to perform these actions one at a time. Furthermore, the specific aggregations of actions or data that a user wishes to perform cannot be predicted; they result from the requirements of each task. Systems, therefore, should allow users to select and act upon arbitrary combinations of data.
6.1.1   PatternThe module view of an architecture pattern for this scenario is shown in Figure 2.
|
Figure 2: Aggregation of Data Architecture Pattern Figures in this file are displayed in a separate browser window. This window will remain open to display figures in this file, although it might be hidden behind other browser windows. |
This pattern has the following components.
The command manager. This component manages the commands that the user generates. A command has an action and one or more subjects that either provide input or accept output from the command. Feedback about the command is generated by the command manager and passed to the presentation. (The output generated by the command is outside of the scope of this scenario.) There are three types of commands. Some commands are independent of groups and group management. These commands are passed directly to the command processor and executed. These commands are outside of the scope of this scenario. A second type of command is concerned with the management of groups – creating a group, adding data to a group, removing data from a group, or deleting a group. These commands are passed to the grouping manager. A third type of command is an action in which one or more of the subjects is a group. This type of command is either passed to the grouping manager or the command processor. The situations where it is passed to one or the other are discussed below.
The grouping manager. This component manages the definition of groups and the addition and deletion of data items from a group. It should, at a minimum, support commands that create and delete groups, and add to and delete from groups. Both data points and other groups should be able to be added and deleted from groups. In the case described below, the grouping manager controls the iteration of commands through the command processor. It accesses the user-visible data and presents groups to support group editing commands.
User-visible application data. This component provides access to the application data that is visible to the user. The data may reside in a single repository (as we have displayed in Figure 2) or it may be distributed through a collection of components. In any case, the application data visible to the user is available both to those components that control data presentation and those that manipulate the data.
There are two options for applying a command to a group, iteration and embedded grouping. Iteration describes the case in which the particular command operates on single arguments. In this case, the grouping manager manages the application of the command to a group. The grouping manager repeatedly invokes the correct command processor on each item in the group. This option assumes that applying a command to a group means applying the command to each element of the group.
The second option is embedded grouping. In this case, the command processor understands groups and can directly operate on a group. The command and its arguments (including the grouped arguments) are sent directly to the command processor. The grouping manager must make available the group elements to the command processor. This can be done synchronously by having the command processor query the grouping manager upon receiving the command, or it can be done asynchronously by having the group identification and the group members recorded in a location available to the command processors.
6.1.2   Allocation to mechanism hierarchySeparation
Data from Commands
In order to allow both the grouping manager and the command processor to manipulate the same data, this data must be kept separate from both components. Such separation also allows presentation commands to read the same data that the grouping manager and command processor manipulate.
Separation
Authoring from Execution
Users author commands for use on aggregates by issuing them to the command manager, but the grouping manager controls iteration in such cases by generating a new set of commands (based on the user’s input) and issuing them in sequence to the command processor. Thus, the user’s command authoring is kept separate from its execution.
6.2 Aggregating CommandsA user may want to complete a long-running, multi-step procedure consisting of several commands. For example, a psychology researcher may wish to execute a batch of commands on a data file during analysis. It could become tedious to invoke these commands one at a time, or to provide parameters for each command as it executes. If the computer is unable to accept the required inputs for this procedure up front, the user will be forced to wait for each input to be requested. Systems should provide a batch or macro capability to allow users to aggregate commands.
6.2.1   PatternThe logical view of an architecture pattern for the authoring portion of this scenario is shown in Figure 3.
|
Figure 3: Authoring of Aggregation of Commands Architecture Pattern Figures in this file are displayed in a separate browser window. This window will remain open to display figures in this file, although it might be hidden behind other browser windows. |
There are two possibilities for authoring aggregates of commands. The first possibility is to have a separate editor that supports this authoring. In this case, the relevant components are the command manager and the authoring component. The command manager recognizes invocation of the authoring editor and those commands that are intended for the authoring editor. The editor creates and stores the aggregated commands. Feedback to the user is through the presentation component. The following items must be specified: Where should output generated during the execution of the aggregated commands be written, and where does input come from that normally would be provided by the user synchronously during execution?
The second architecture possibility is to author by demonstration. That is, the user executes the commands that are desired synchronously. The authoring editor monitors those commands and saves them as an aggregated set that can be subsequently invoked. These aggregated commands are usually edited prior to final saving for execution. In this case, the command manager must communicate the commands both to the command processor for execution and to the authoring editor for inclusion in the aggregate. The authoring editor and the command processor may communicate if additional information about parameters or data must be saved in the aggregated command. We do not display this communication since it may not be necessary.
The execution of the aggregates can also be explained using Figure 3. In this case, the user invokes the aggregated command. The command manager must communicate with the authoring editor to retrieve the aggregated command. (This could be as simple as retrieving it from a file where the authoring editor has stored it). This necessity for communication is the source of the data flow from the authoring editor to the command manager. The command manager then sends the commands one at a time to the command processor. The command manager must be informed of the source of any required synchronous user input and the destination of any generated error messages.
6.2.2   Allocation to mechanism hierarchySeparation
Authoring from Execution
Users specify aggregates by authoring them in the authoring editor. Since the command manager controls the execution of the commands, authoring and execution are separated.
Replication
Commands
More than one set of aggregated commands might be applied by a user to achieve the same goals. Commands are effectively replicated in this case.
Recording
In systems where demonstration is used to specify command aggregates (e.g., macros in Microsoft Word), the authoring editor must be able to record the user’s actions.
6.3 Canceling CommandA user invokes an operation, then no longer wants the operation to be performed. The user now wants to stop the operation rather than wait for it to complete. It does not matter why the user launched the operation. The mouse could have slipped. The user could have mistaken one command for another. The user could have decided to invoke another operation. For these reasons (and many more), systems should allow users to cancel operations.
6.3.1   PatternWe first present the module view that enumerates the components involved and their responsibilities. We then present a sequence chart that shows how the components interact.
Figure 4 presents the module view of the cancellation architectural style. It has the following components together with their responsibilities. (Note that these functions may or may not be implemented as separate software components, such as classes or threads.)
- Activity Component. Activity components perform the activities that may be cancelled. They must cooperate with the controller to provide information about the resource that they use and their collaborations. They must also have a mechanism for retaining sufficient information about the system state be able to restore that state at any time. The mechanism will be exercised by the cancellation component but the active components must prepare resources so that the cancellation component can, in fact, exercise the mechanisms.
- Cancellation Listener. This component listens for the user to request canceling the active components. It must inform the user that it has received the cancellation request. It then informs the cancellation controller. If necessary, it may spawn a new thread to control the operation of the cancellation component.
- Cancellation Controller. This component can terminate the active thread, return the persistent resources to their state prior to invoking the active components, release non-preemptable resources, provide feedback to the user about progress and the result of the cancellation, and inform collaborating components of the termination of the active thread. It is responsible for gathering information about the resources used by the active components and the collaborating components.
- Collaborators. These components are responsible for receiving information about the termination of the active components.
|
Figure 4: Module View of Cancellation Architecture Pattern Figures in this file are displayed in a separate browser window. This window will remain open to display figures in this file, although it might be hidden behind other browser windows. |
Figure 5 shows a representation of the threads of this pattern. The following logically distinct threads of activity exist, although they may be implemented together.
- The listener thread. This thread interacts with the user. It provides the user with a means to indicate what is to be cancelled.
- The cancellation control thread. This thread manages the cancellation activities. It must be independent from the active thread.
- The active thread. This is the running thread that the user wishes to cancel. The activities running under the control of the active thread are those that are to be cancelled.
- The collaborating processes thread. This may be a collection of threads but we model it as a single thread. This thread manages those processes that collaborate with the active thread.
|
Figure 5: Cancellation Pattern - Thread View Figures in this file are displayed in a separate browser window. This window will remain open to display figures in this file, although it might be hidden behind other browser windows. |
We will now describe how these threads interact. The user sends a cancellation stimulus to the cancellation listener component running in the listener thread. This thread then provides feedback to the user that the cancel request has been received, and lets the cancellation controller know that it should carry out that the cancel activity.
The cancellation controller is a thread that executes the cancellation. The active thread should not be expected to listen for a cancel request since it may be blocked for some reason or it may be in an infinite loop. The cancellation component carries out four activities:
- Terminate the active thread.
- Inform the user of the progress and results of the cancellation.
- Return the system to its state prior to the invocation of the active thread. This involves
- restoring any persistent resources to their state prior to the invocation of the active thread
- releasing non-preemptive resources acquired by the active thread
- Inform threads collaborating with the active thread that it has been terminated.
The first of these is straightforward. Presumably, the thread control mechanisms of the operating system permit terminating a thread. The second activity is also straightforward. The user should be informed of both the progress and the results of the cancellation. The third activity (returning to prior state) requires that the cancellation controller be aware of the mechanisms for restoring persistent resources to their states prior to invoking the active thread. For example, operating system resources may need to be reallocated, files may need to be restored, network connections may need to be re-established, etc. The cancellation controller must also be aware of the resources acquired by the active components, and these resources must be freed. This awareness can be achieved by a variety of mechanisms. The activity components can report resources acquired to the cancellation controller, the cancellation controller can intercept requests for resources, or the various resource managers can provide this information to the cancellation controller.
The fourth activity (informing collaborating threads) also requires knowledge on the part of the cancellation controller. The cancellation controller must be informed of collaborations, either synchronization or data communication, that the active thread has with other threads. The controller doesn’t necessarily need to be informed of the state of these collaborations; it can simply inform each of the collaborating threads of the termination of the active thread. Then it becomes the responsibility of the collaborating threads to perform the correct actions, including providing information to the user about the progress and results of these cancellation requests. This can be complicated. It depends on the type of collaboration and the extent to which the collaborating components depend on the completion of the active components. One possibility is to treat the information as a cancellation request for the collaborating components. In this case, a recursive use of the pattern will achieve the desired results. Other types of collaborations may not require cancellation. In any case, a decision must be made as to the desired result after the collaboration components have been informed of the cancellation of the active components.
6.3.2   Allocation to mechanism hierarchyPreemptive Scheduling
To adequately implement cancellation, the cancellation listener and cancellation controller must occupy independent threads.
Models
System
After a command has been cancelled, the system must consult an explicit model of itself in order to predict state restoration time and to report progress.
Recording
The cancellation component must record its initial state so that the system can be returned to the state prior to the invocation of the cancelled components.
6.4 Using Applications ConcurrentlyA user may want to work with arbitrary combinations of applications concurrently. These applications may interfere with each other. For example, some versions of IBM® ViaVoice and Microsoft® Word contend for control of the cursor with unpredictable results. Systems should ensure that users can employ multiple applications concurrently without conflict.
(See: Supporting Multiple Activities).
6.4.1   PatternFigure 6 gives a module view of a possible pattern.
|
Figure 6: Module View of Concurrent Application Use Figures in this file are displayed in a separate browser window. This window will remain open to display figures in this file, although it might be hidden behind other browser windows. |
This pattern describes a system resource manager that applications must use to get shared resources such as the cursor or memory. The applications are responsible for requesting necessary resources from this resource manager and then querying for state of shared resources when they are being used. The resource manager adjudicates conflicting requests for resources and manages all system resources, whether sharable or only serially usable.
6.4.2   Allocation to mechanism hierarchySeparation
Encapsulation of function
The resource manager is kept separate from other applications.
Models
System
The resource manager maintains an explicit model of the system to track resources and their consumers.
6.5 Checking for CorrectnessA user may make an error that he or she does not notice. However, human error is frequently circumscribed by the structure of the system; the nature of the task at hand, and by predictable perceptual, cognitive, and motor limitations. For example, users often type "hte" instead of "the" in word processors. The frequency of the word "the" in English and the fact that "hte" is not an English word, combined with the frequency of typing errors that involve switching letters typed by alternate hands, make automatically correcting to "the" almost always appropriate. Computer-aided correction becomes both possible and appropriate under such circumstances. Depending on context, error correction can be enforced directly (e.g., automatic text replacement, fields that only accept numbers) or suggested through system prompts.
6.5.1   PatternFigure 7 gives a module view of an architecture pattern for a correctness checker. The application data is maintained separately from the application so that it is accessible to the correctness checker. The correctness checker maintains a model of the correct input so that it can determine when a potential error occurs. In the sample pattern, it reports this error to the user through the presentation. There may be cases when errors are automatically corrected.
|
Figure 7: Correctness Figures in this file are displayed in a separate browser window. This window will remain open to display figures in this file, although it might be hidden behind other browser windows. |
This figure assumes that the active application and the correctness checker operate on different threads of control. In this way, error detection can be done without user input. It also can be done asynchronously, although this is not displayed in the module view.
6.5.2   Allocation to mechanism hierarchySeparation
Data from Commands
When the correctness checker and the data operate independently, a variety of different checking mechanisms can be turned on or off without affecting the data itself.
Preemptive Scheduling
Correctness must be checked while the user performs operations. This requires an independent thread.
Mode
Task
Systems can employ a model of the task to identify when, what, and how to correct. For example, knowing that sentences usually start with capital letters would allow an application to correct a lower case letter that begins a sentence.
Models
User
Systems can employ a model of the user to identify when, what, and how to correct. For example, a model of human typing is used to know that "teh" is a common mistyping of "the."
Models
System
A system can employ a model of itself to identify when, what, and how to correct. For example, knowing which toolbar buttons are adjacent might help the system conclude that a user hit the wrong button when a tool selection doesn’t make sense according to context.
6.6 Maintaining Device IndependenceA user attempts to install a new device. The device may conflict with other devices already present in the system. Alternatively, the device may not function in certain specific applications. For example, a microphone that uses the Universal Serial Bus (USB) may fail to function with older sound software. Systems should be designed to reduce the severity and frequency of device conflicts. When device conflicts occur, the system should provide the information necessary to either solve the problem or seek assistance. (Devices include printers, storage/media, and I/O apparatus.)
6.6.1   PatternFigure 8 shows a module view of a virtual device layer. Applications access physical devices through a virtual device that defines and abstracts how the devices should be controlled. The virtual device layer accesses devices through physical device drivers that do the actual control. The virtual device layer translates the virtual device into the various physical devices. This assumes that a collection of device types has been defined and that virtual device layers exist for each category of device types.
|
Figure 8: Virtual Device Layer Figures in this file are displayed in a separate browser window. This window will remain open to display figures in this file, although it might be hidden behind other browser windows. |
Indirection
Function
Commands for interacting with various devices can be abstracted. Such indirection hides distinctions between physical devices by providing an encapsulated virtual device interface.
Models
System
The system can maintain a model of itself based on data from the virtual device interface to identify and track device conflicts and to provide the information needed to resolve them.
6.7 Evaluating the SystemA system designer or administrator may be unable to test a system for robustness, correctness, or usability in a systematic fashion. For example, the usability expert on a development team might want to log test users’ keystrokes, but may not have the facilities to do so. Systems should include test points and data gathering capabilities to facilitate evaluation.
6.7.1   Pattern
Figure 9 shows the module view of a data-recording mechanism. This module provides a means for recording any data of interest. Recorded data may include keystrokes, errors, user commands, or any other data of interest.
|
Figure 9: Data Recording Figures in this file are displayed in a separate browser window. This window will remain open to display figures in this file, although it might be hidden behind other browser windows. |
There should be tools that can access the recorded data and provide a variety of different analyses, such as examining the data for patterns of errors, user confusion, or critical incidents. The analysis tools associated with the recording of data are not shown.
6.7.2   Allocation to mechanism hierarchy
Indirection
Data
When evaluating a system, test data may need to "masquerade" as user data for simulation purposes. Data indirection can be used to facilitate this process.
Recording
The data recorder records the data needed to analyze the results of test cases and other evaluations.
6.8 Recovering from FailureA system may suddenly stop functioning while a user is working. Such failures might include a loss of network connectivity or hard drive failure in a user’s PC. In these or other cases, valuable data or effort may be lost. Users should be provided with the means to reduce the amount of work lost from system failures.
6.8.1   Pattern
There are elaborate mechanisms to automatically recover from failures that involve redundant computations. These mechanisms are intended to reduce down time for systems that require high availability. We here describe a mechanism that is intended to apply in situations in which the availability requirement is less stringent.
The mechanism maintains periodic checkpoints of application state. That is, the data necessary for the application to execute is recorded when the system is in a consistent state. The system then has a restart mode in which it reads the recorded data and resumes computation from the last state recorded. Figure 10 shows the key components. Each component is responsible for checking its data and restoring its state from the checked data. This can be done individually by the components or globally through a data repository or some mixture. The important aspect is that the checked data be consistent. This is the role of the checkpoint synchronizer. It informs the components that maintain application data when it is time for a checkpoint and ensures that this action is performed with consistent data.
|
Figure 10: Perform Checkpoint Figures in this file are displayed in a separate browser window. This window will remain open to display figures in this file, although it might be hidden behind other browser windows. |
Recording
The checkpoint synchronizer informs components to record all relevant data to minimize loss in the event of failure.
6.9 Retrieving Forgotten PasswordsA user may forget a password. Retrieving and/or changing it may be difficult or may cause lapses in security. Systems should provide alternative, secure mechanisms to grant users access. For example, some online stores ask each user for a maiden name, birthday, or the name of a favorite pet in lieu of a forgotten password.
6.9.1   Pattern
The key element of the pattern is to have authentication encapsulated. There are a variety of policies and mechanisms that can be used for authentication. These include secret questions, mailing a new password to a previously authenticated mail address, and biologically-based mechanisms such as finger print recognition or retinal scan. The policy and mechanism to be used depends on the level of security to be implemented and the context of use. All data relating to authentication should be stored using encryption so the information is not available if the storage media is compromised.
6.9.2   Allocation to mechanism hierarchy
Separation
Encapsulation of function
The authentication component must be encapsulated and passwords encrypted to prevent security breaches if the media that stores it becomes compromised.
6.10 Providing Good HelpA user needs help. The user may find, however, that a system’s help procedures do not adapt adequately to the context. For example, a user’s computer may crash. After rebooting, the help system automatically opens to a general table of contents rather than to a section on restoring lost data or searching for conflicts. Help content may also lack the depth of information required to address the user’s problem. For example, an operating system’s help area may contain an entry on customizing the desktop with an image, but may fail to provide a list of the types of image files that can be used. Help procedures should be context dependent and sufficiently complete to assist users in solving problems.
6.10.1   Pattern
In the pattern, we focus on achieving context dependency. The content and verboseness of the help messages is not an architectural issue. Having context dependent help requires two types of knowledge: knowledge of what the user wishes to do and knowledge of the current state of the system. Knowledge of the current state of the system can be gathered explicitly. Knowledge of what the user wishes to do, however, must be inferred. This inference comes from what the user has already done, the current system state, and a model of the tasks the user might wish to do. The task model should be separated from other functions of the system, since it is likely to change as it is refined. In other words, there should be an explicit task model developed that supports context dependent help.
Figure 11 presents the pattern. The context determiner is responsible for determining the current context so that the help system can show the correct information. The system state provides input to the context determiner without specifying its source. Finally, the task model is a separate encapsulated component, for the reasons we have already mentioned. We do not show the run-time interactions, but there are two cases. If the context dependent help is automatically invoked, it should run in a thread that is separate from the thread of the user activity. If context dependent help depends on user invocation, then its thread structure can be synchronous with the user’s request.
|
Figure 11: Context Dependent Help Figures in this file are displayed in a separate browser window. This window will remain open to display figures in this file, although it might be hidden behind other browser windows. |
Preemptive Scheduling
If a system is to offer help automatically when it perceives that a user is in trouble, the system must support scheduling; the help system and context determiner will occupy an independent thread.
Models
Task
A model of the task can be used to determine what help information to present first when either the user requests help or the help system determines that the user is in trouble.
Models
User
A model of the user can be used to determine what level of help to provide and how likely the user is to encounter problems (i.e., is the user a novice or an expert?). This model can also help determine what information to present.
6.11 Reusing InformationA user may wish to move data from one part of a system to another. For example, a telemarketer may wish to move a large list of phone numbers from a word processor to a database. Re-entering this data by hand could be tedious and/or excessively time-consuming. Users should be provided with automatic (e.g., data propagation) or manual (e.g., cut and paste) data transports between different parts of a system. When such transports are available and easy to use, the user’s ability to gain insight through multiple perspectives and/or analysis techniques will be enhanced.
6.11.1   Pattern
Figure 12 shows the components that implement information reuse. The interpretation and persistence of these components, however, depend on the type of information reuse being implemented. We discuss two cases, automatic and manual.
If manual cut and paste is being implemented, then the user (somehow) indicates the data to be transferred. This data is, typically, available on the display, so the information source is the presentation component. The information is then placed in the information reuse repository. Finally, the user indicates the sink for the data and the data is passed to the source as if it were input data. One key to cut and paste is to maintain type information about the data. The source provides the type of the data being transferred and the sink indicates whether it can accept data of that type. If not, then a type conversion must be made between the type of the data at the source and an acceptable type at the sink. Usually, system-wide conventions concerning type have been established so the source and sink can accommodate the same types.
If automatic data propagation is being implemented, then type information is again a crucial element. In this case, the information reuse repository is maintained as a blackboard. The sink(s) register interest in items of a particular data type. The source publishes current information of the particular data type. For example, if the sink is a form that wants to know the user name, any component of the system that knows it places that name in the repository. When the sink is invoked, it registers for the user name and the current name is given to the sink.
The type of information used in data propagation is far richer than the type used in cut and paste. A name, for example, in cut and paste can be treated as a sequence of letters. In data propagation, the name should be identified as "proper name" or some other type. Usually, a data dictionary is defined that enumerates all the valid types known to the information reuse repository.
|
Figure 12: Information Re-Use Figures in this file are displayed in a separate browser window. This window will remain open to display figures in this file, although it might be hidden behind other browser windows. |
Indirection
Data
The information reuse repository acts as an indirection intermediary by separating the data producer and consumer.
6.12 Supporting International UseA user may want to configure an application to communicate in his or her language or according to the norms of his or her culture. For example, a Japanese user may wish to configure the operating system to support a different keyboard layout. However, an application developed in one culture may contain elements that are confusing, offensive, or otherwise inappropriate in another. Systems should be easily configurable for deployment in multiple cultures
6.12.1   Pattern
Figure 13 gives the module view of the pattern. Some of the complications are screen real estate management, screen painting, and deployment strategy.
Screen real estate management
The same phrase in different languages may require a different amount of characters even when the languages utilize the same alphabet. Thus, screen layout may be different in different languages. One technique for managing this is to have a template supply the screen layout. This template would be interpreted at runtime by the presentation component. The template is accessible through the customization component.
Screen painting
Different languages may use a different order of painting. Latin-based languages are read from left to right. Hebrew and Arabic languages are read right to left. Some Oriental languages are read top to bottom. It is the responsibility of the presentation component to paint the screen and retrieve input in the correct fashion for the current user.
Deployment strategy
The architect must decide whether to have a single deployment support multiple languages (such as an ATM machine) or whether each deployed system only supports a single language (such as software intended for use within an office where the users’ language is known). If a single deployment supports multiple languages, all of the language dictionaries must be present and the presentation must decide on the layout at runtime. This decision is made based on the user’s identity or expressed preference. If a single deployment only supports one language then only the dictionary for that language needs to be present, and different versions of the presentation component can be created.
|
Figure 13: Internationalization Figures in this file are displayed in a separate browser window. This window will remain open to display figures in this file, although it might be hidden behind other browser windows. |
Separation
Data from view of data
By separating the core data of a system from the view of that data, the presentation component can map user-visible data into a form that is linguistically and culturally appropriate.
Models
User
The presentation component accesses user-supplied customization specifications to configure itself appropriately. These specifications model the user.
6.13 Leveraging Human KnowledgePeople use what they already know when approaching new situations. Such situations may include using new applications on a familiar platform, a new version of a familiar application, or a new product in an established product line.
New approaches usually bring new functionality or power. When, however, users are unable to apply what they already know, a corresponding cost in productivity and training time is incurred. For example, new versions of applications often assign items to different menus or change their names. As a result, users skilled in the older version are reduced to the level of novices again, searching menus for the function they know exists.
System designers should strive to develop upgrades that leverage users’ knowledge of prior systems and allow them to move quickly and efficiently to the new system.
6.13.1   Pattern
There are two facets to this scenario. One facet is platform standards. The user can apply knowledge from one application when using another. The second facet is to have multiple interfaces when making substantive changes to an application. The user can then choose an interface. We discuss these in turn.
Platform standardsThe essence of maintaining platform standards is to separate the look and feel of an application or command from the functional aspects of that command. There can then be libraries that implement a standard look and feel for a particular platform. The approach to this separation is discussed in the scenario "Modifying Interfaces."
Multiple interfaces
Figure 13 gives a module view of maintaining multiple interfaces for the purpose of supporting internationalization. Having multiple interfaces for the purpose of backward compatibility can be viewed as simultaneously supporting two languages. One difference is that the two interfaces may not support exactly the same set of commands. This structure will support the case where the commands available through the new interface are a superset of the commands available through the old.
6.13.2   Allocation to mechanism hierarchy
Separation
Encapsulation of function
Toolkits and libraries are encapsulated to embody the standards and the Application Programming Interface (API) of a given platform.
Separation
Data from view
By separating the core data of a system from the view of that data, multiple interfaces can be offered to facilitate the transition from one version of a product to another.
6.14 Modifying InterfacesIterative design process is the lifeblood of current software development practice, yet a system developer may find it prohibitively difficult to change the user interface of an application to reflect new functions and/or new presentation desires. System designers should ensure that their user interfaces can be easily modified.
6.14.1   Pattern
Two basic techniques to support modifiability are indirection (both data and control) and encapsulation (information hiding) of coherent computations. Data indirection techniques include repositories and publish/subscribe. Control indirection techniques include virtual machines. This is too complicated a topic to be easily summarized here. See Chapter 6 of Software Architecture in Practice for a discussion of several user interface reference models [Bass 1998].
To support modifiability, the architect should enumerate a list of likely change scenarios and ensure that the architecture will support them.
6.14.2   Allocation to mechanism hierarchy
Separation
Encapsulation of function
Encapsulating all user interface functionality away from the core of the system ("Everything Else") allows designers to modify the user interface more easily.
Indirection
Function
The use of an intermediary such as the dialogue manager in the Seeheim Model or the Control in the PAC model is indirection of function. These models are discussed in Chapter 6 of Software Architecture in Practice [Bass 1998].
Indirection
Data
Indirection of data refers to the separation of application data from the view of that data. It occurs in virtually all of the models discussed in Chapter 6 of Software Architecture in Practice [Bass 1998].
6.15 Supporting Multiple ActivitiesUsers often need to work on multiple tasks more or less simultaneously (e.g., check mail and write a paper). A system or its applications should allow the user to switch quickly back and forth between these tasks.
6.15.1   Pattern
The operating system should provide for independent threads of control and for context changes between one thread and another. One problem arises because the operating system must know what an application considers its context. Thus, key bindings as shortcuts may differ from application to application, and the current key bindings should always reflect the active application. Applications should register items so they can be saved and restored when a context switch is made.
6.15.2   Allocation to mechanism hierarchy
Separation
Encapsulation of function
The context saver separates application specific environment data like key bindings from the applications themselves.
Preemptive Scheduling
Systems that support multiple threads allow for robust, fast context switching.
6.16 Navigating Within a Single ViewA user may want to navigate from data visible on-screen to data not currently displayed. For example, he or she may wish to jump from the letter "A" to the letter "Q" in an online encyclopedia without consulting the table of contents. If the system takes too long to display the new data or if the user must execute a cumbersome command sequence to arrive at her or his destination, the user’s time will be wasted. System designers should strive to ensure that users can navigate within a view easily and attempt to keep wait times reasonably short.
(See: Working at the User’s Pace) 6.16.1   PatternCaching improves performance by replicating data in a location with faster retrieval time. For example, browsers cache copies of Web pages so users can return to those pages quickly.
Figure 14 shows two components that are used to manage caching. One component holds the data with fast access as well as an algorithm that is used to update that data. Usually the cache uses fewer resources than the main data store and so holds a smaller amount of data; This makes it necessary to have an updating algorithm. If the data in the cache is changed by the application, there must also be an algorithm for updating the main data store.
|
Figure 14: Navigation Figures in this file are displayed in a separate browser window. This window will remain open to display figures in this file, although it might be hidden behind other browser windows. |
Replication
Data
By replicating data from a device with slow retrieval times and storing it in a high-speed cache, navigation wait times can be reduced.
6.17 Observing System StateA user may not be presented with the system state data necessary to operate the system (e.g., uninformative error messages, no file size given for folders). Alternatively, the system state may be presented in a way that violates human tolerances (e.g., is presented too quickly for people to read. See: Working at the User’s Pace). The system state may also be presented in an unclear fashion, thereby confusing the user. System designers should account for human needs and capabilities when deciding what aspects of system state to display and how to present them.
A special case of Observing System State occurs when a user is unable to determine the level of security for data entered into a system. Such experiences may make the user hesitate to use the system or avoid it altogether.
6.17.1   Pattern
Two aspects to viewing the system state are making the data available and taking the initiative in presenting the data.
Making the data available
Data that represents the system state should be collected into a component that can make it accessible to the user. Associated with each data item should be information such as type of data, a refresh rate (see Working at the User’s Pace), and other attributes of interest. Once the data has been collected, it can be accessed through commands and specialized applications.
Taking the initiative in presenting data
If the data is to be presented upon user request, then no special architecture mechanism is needed. If the data is to be presented on the system’s initiative, then a model of the user is needed in order to decide what circumstances will require the system to take initiative.
6.17.2   Allocation to mechanism hierarchy
Separation
Data from Commands
State data is stored in a repository apart from the rest of the system.
Preemptive Scheduling
If data is to be presented on the system’s initiative, a component must occupy a separate thread to monitor the user’s actions and determine when to present new data or update the data currently displayed.
Models
Task
If data is to be presented on the system’s initiative, the system can consult a model of the task to determine what information to present to the user.
Models
User
If data is to be presented on the system’s initiative, the system can consult a model of the user to determine what information to present.
Models
System
If data is to be presented on the system’s initiative, the system can consult a model of itself to determine what information to present.
6.18 Working at the User’s PaceA system might not accommodate a user’s pace in performing an operation. This may make the user feel hurried or frustrated. For example, ATMs often beep incessantly when a user "fails" to insert an envelope in time. Also, Microsoft Word’s scrolling algorithm does not take system speed into account and becomes unusable on fast systems (the data flies by too quickly for human comfort). Systems should account for human needs and capabilities when pacing the stages in an interaction. Systems should also allow users to adjust this pace as needed.
6.18.1   Pattern
The system maintains a model of itself as well as a model of the user. It uses the model of the user to determine the correct pace or users expectations. It uses to model of itself to predict information that will be of interest to the user, such as time remaining to complete a task.
These models should operate on a thread distinct from the main activity thread so the computations and displays associated with pace control can be completed regardless of the state of the main activity computation.
6.18.2   Allocation to mechanism hierarchy
Models
Task
The system can use a model of the task to determine what pace to use for prompting. For example, an ATM should know that if a user has asked to deposit money, it might take her or him a while to fill and seal the envelope. The system should not beep at the user during this time.
Models
User
The system can also use a model of the user to set the pace. For example, novice users may take longer to perform tasks than experts.
Preemptive Scheduling
The model of the user and model of the task should operate on a thread distinct from the main activity thread so the computations and displays associated with pace control can be completed and updated regardless of the state of the main activity.
6.19 Predicting Task DurationA user may want to work on another task while a system completes a long running operation. For example, an animator may want to leave the office to make copies or to eat while a computer renders frames. If systems do not provide expected task durations, users will be unable to make informed decisions about what to do while the computer "works." Thus, systems should present expected task durations.
6.19.1   Pattern
(See: Working at the User’s Pace)
6.19.2   Allocation to mechanism hierarchyModels
Task
A model of the task can determine what steps are likely to be performed in an operation. The system then can predict total completion time that spans more than one operation. For example, if users install several parts of an application in sequence, the system can predict a total install time.
Models
System
A model of the system can be used to determine how much work is left to do and, hence, to predict completion time (percent complete, etc.).
Preemptive Scheduling
Scheduling is necessary in systems that present progress feedback. One thread is needed for the progress monitor and one is needed for the activity being monitored.
6.20 Supporting Comprehensive SearchingA user wants to search some files or some aspects of those files for various types of content. For example, a user may wish to search text for a specific string or all movies for a particular frame. Search capabilities may be inconsistent across different systems and media, thereby limiting the user’s opportunity to work. Systems should allow users to search data in a comprehensive and consistent manner by relevant criteria.
6.20.1   Pattern
The architecture pattern for comprehensive search is shown in Figure 15. It uses a search registry to satisfy the search requests. Various applications that have searchable information can register with the search registry. Thus, a file manager might register with the search registry so it can search file names and content. An application requests a search by specifying the types of information that should be reviewed and the scope of the review, the search manager then delegates the search request to the entities that have registered with it. Results are sent back to the application that originally requested the search.
Returning information to the application must allow for appropriate feedback to the user. For example, if the search is for a word in a document, the return should be a reference to that word rather than the word itself so the user can see the word highlighted within context.
|
Figure 15: Search Figures in this file are displayed in a separate browser window. This window will remain open to display figures in this file, although it might be hidden behind other browser windows. |
Separation
Encapsulation of function
The search registry is separated from individual applications and files to allow users to instantiate a search from within any application.
Indirection
Function
The search registry operates as an intermediary between the applications requesting searches and the applications executing them.
6.21 Supporting UndoA user performs an operation, then no longer wants the effect of that operation. For example, a user may accidentally delete a paragraph in a document and wish to restore it. The system should allow the user to return to the state before that operation was performed. Furthermore, it is desirable that the user then be able to undo the prior operation (multi-level undo).
6.21.1   Pattern
Figure 16 shows the key components in implementing an undo capability. Each component that is involved in an undo sends relevant data to a transaction manager. The data is viewed as a transaction. That is, data items are grouped together and form an atomic unit. All of the data has been applied or none of it has been applied. (Transactions can be rolled off and that is "undo.")
Using a global transaction manager rather than relying on each component to perform its own undo has an advantage: the number of steps that can be undone is arbitrary. The only limit is the amount of storage on the media used for the undo capability. Furthermore, the granularity of the undo (e.g., are keystrokes undone or commands) is then dependent on the component rather than on some system-wide decision. That is, suppose the current granularity of the undo is at the command level and there is a decision made to change it to the keystroke level. Then all that is necessary is to enter the keystrokes into the transaction manager and the commands do not need to be modified. The transaction stack will go from just having the data to undo the commands to having the data to undo the keystrokes.
|
Figure 16: Undo Figures in this file are displayed in a separate browser window. This window will remain open to display figures in this file, although it might be hidden behind other browser windows. |
Recording
The transaction manager must store state information each time an "undoable" command is executed in order to later "roll back" through one or more previous states.
6.22 Working in an Unfamiliar ContextA user needs to work on a problem in a different context. Discrepancies between this new context and the one the user is accustomed to may interfere with the ability to work. For example, a clerk in business office A wants to post a payment for a customer of business unit B. Each business unit has a unique user interface, and the clerk has only used unit A’s previously. The clerk may have trouble adapting to business unit B’s interface (same system, unfamiliar context.) Systems should provide a novice (verbose) interface to offer guidance to users operating in unfamiliar contexts.
6.22.1   Pattern
This pattern requires maintaining two different interfaces simultaneously for the same system. This is the same pattern described in Supporting Internationalization and Leveraging Human Knowledge.
6.22.2   Allocation to mechanism hierarchy
Separation
Data from View
The "verbose" and "standard" user interfaces are kept separate from the functional core of the system to easily switch between them.
Replication
Commands
Since two user interfaces are offered, commands that are available in both are replicated.
Model
Users
The system consults a model of the user to determine which interface to present.
6.23 Verifying ResourcesAn application may fail to verify that necessary resources exist before beginning an operation. This failure may cause errors to occur unexpectedly during execution. For example, some versions of Adobe® PhotoShop® may begin to save a file only to run out of disk space before completing the operation. Applications should verify that all necessary resources are available before beginning an operation.
6.23.1   Pattern
This is very similar to "Using Applications Concurrently." The application must verify that necessary resources are available from a resource manager and inform the user if sufficient resources are not available to complete a task.
6.23.2   Allocation to mechanism hierarchy
Separation
Encapsulation of function
The resource manager is encapsulated apart from the rest of the system.
System
The resource manager must maintain a model of the system to know which resources to verify and to determine a plan of action in the event that needed resources are unavailable.
6.24 Operating Consistently Across ViewsA user may become confused by functional deviations between different views of the same data. Commands that had been available in one view may become unavailable in another or may require different access methods. For example, users cannot run a spell check in the Outline View utility found in a mid-90’s version of Microsoft Word. Systems should make commands available based on the type and content of a user’s data, rather than the current view of that data, as long as those operations make sense in the current view.
For example, allowing users to perform operations on individual points in a scatter plot while viewing the plot at such a magnification that individual points cannot be visually distinguished does not make sense. A naïve user is likely to destroy the underlying data. The system should prevent selection of single points when their density exceeds the resolution of the screen, and inform the user how to zoom in, access the data in a more detailed view, or otherwise act on single data points.
(See: Providing Good Help and Supporting Visualization)
6.24.1   PatternFigure 17 shows the relevant components that enable consistent operation across views. The data that is being viewed should be separated from the view description. The presentation maps the data through the description of the user’s requested view. Commands are also separated from the data. This allows the commands to operate on the data without knowing the view of the data requested by the user.
|
Figure 17: Consistent Operation Figures in this file are displayed in a separate browser window. This window will remain open to display figures in this file, although it might be hidden behind other browser windows. |
Separation
Data from Commands
In systems in which users select the current view from a toolbar, the view change commands are separated from the view description.
Separation
Data from View
When the view description is kept separate from the viewed data, commands that manipulate the data can be executed without referencing the current view.
6.25 Making Views AccessibleA user may want to see data from another point of view. For example, a user may wish to see the outline of a long document and the details of the prose. If certain views become unavailable in certain modes of operation, or if switching between views is cumbersome, the user’s ability to gain insight through multiple perspectives will be constrained.
6.25.1   Pattern
Figure 17 also satisfies this scenario. Switching between views is a matter of changing the active view description and should be independent of the mode or of what is currently on the screen.
6.25.2   Allocation to mechanism hierarchy
Separation
Data from Commands
In systems where users select the current view from a toolbar, the view change commands are separated from the view description.
Separation
Data from View
When the view description is kept separate from the viewed data, the system can change views without referencing the current view.
6.26 Supporting VisualizationA user wishes to see data from a different viewpoint. Systems should provide a reasonable set of task-related views to enhance users’ ability to gain additional insight while solving problems. For example, Microsoft Word provides several views to help users compose documents, including Outline and Page Layout modes.
6.26.1   Pattern
Figure 17 also satisfies this scenario. Task-related views can be described in the view description and adding views should be an easy set of modifications. Switching between views then is a matter of changing the active view description and should be independent of the mode or of what is currently on the screen.
6.26.2   Allocation to mechanism hierarchy
Separation
Data from Commands
In systems where users select the current view from a toolbar, the view change commands are separated from the view description.
Separation
Data from View
Each view of the data exists independently from the data itself.
[Title Page] [Abstract] [Figures]