Chapter 6: Presentation Layer Guidelines
For more details of the topics covered in this guide, see Contents of the Guide.
- General Design Considerations
- Specific Design Issues
- Technology Considerations
- Performance Considerations
- Design Steps for the Presentation Layer
- Relevant Design Patterns
- patterns & practices Offerings
- Additional Resources
This chapter describes the key guidelines for designing the presentation layer of an application. It will help you to understand how the presentation layer fits into the typical layered application architecture, the components it usually contains, and the key issues you face when designing the presentation layer. You will see guidelines for design, the recommended design steps, relevant design patterns, and technology options.
The presentation layer contains the components that implement and display the user interface and manage user interaction. This layer includes controls for user input and display, in addition to components that organize user interaction. Figure 1 shows how the presentation layer fits into a common application architecture.
The presentation layer will usually include the following:
- User Interface components. These are the application's visual elements used to display information to the user and accept user input.
- Presentation Logic components. Presentation logic is the application code that defines the logical behavior and structure of the application in a way that is independent of any specific user interface implementation. When implementing the Separated Presentation pattern, the presentation logic components may include Presenter, Presentation Model, and ViewModel components. The presentation layer may also include Presentation Layer Model components that encapsulate the data from your business layer, or Presentation Entity components that encapsulate business logic and data in a form that is easily consumable by the presentation layer.
For more information about the components commonly used in the presentation layer, see Chapter 10 "Component Guidelines." For information about designing presentation layer components, see Chapter 11 "Designing Presentation Components."
General Design Considerations
There are several key factors that you should consider when designing your presentation layer. Use the following principles to ensure that your design meets the requirements for your application, and follows best practices:
- Choose the appropriate application type. The application type you choose will have considerable impact on your options for the presentation layer. Determine if you will implement a rich (smart) client, a Web client, or a rich Internet application (RIA). Base your decision on application requirements, and on organizational and infrastructure constraints. For information on the main application archetypes, and their benefits and liabilities, see Chapter 20 "Choosing an Application Type."
- Choose the appropriate UI technology. Different application types provide different sets of technologies that you can use to develop the presentation layer. Each technology type has distinct advantages that can affect your ability to create a suitable presentation layer design. For information on the technologies available for each application type, see Appendix B "Presentation Technology Matrix."
- Use the relevant patterns. Review the presentation layer patterns (listed at the end of this chapter) for proven solutions to common presentation problems. Keep in mind that not all patterns apply equally to all archetypes. However, the general pattern of Separated Presentation, which separates presentation specific concerns from the underlying application logic, applies to all application types. Specific patterns such as MVC, MVP, and Supervising Presenter are commonly used in presentation layer design of rich client applications and RIAs. Variants of the Model-View-Controller (MVC) and Model-View-Presenter (MVP) patterns can be used in Web applications.
- Design for separation of concerns. Use dedicated UI components that focus on rendering, display, and user interaction. Consider using dedicated presentation logic components to manage the processing of user interaction where this is complex or where you want to be able to unit test it. Also, consider using dedicated presentation entities to represent your business logic and data in a form that is easily consumable by your UI and presentation logic components. Presentation entities encapsulate within the presentation layer the business logic and data from your business layer, for use in much the same way as business entities are used in the business layer. For more information about the different types of presentation layer components you may use, see Chapter 11 "Designing Presentation Components."
- Consider human interface guidelines. Implement your organization's guidelines for UI design, including factors such as accessibility, localization, and usability when designing the presentation layer. Review established UI guidelines for interactivity, usability, system compatibility, conformance, and relevant UI design patterns based on the client type and the technologies that you choose, and apply those applicable to your application design and requirements.
- Adhere to user driven design principles. Before designing your presentation layer, understand your customer. Use surveys, usability studies, and interviews to determine the best presentation design to meet your customer's requirements.
Specific Design Issues
There are several common issues that you must consider as your develop your design. These issues can be categorized into specific areas of the design. The following sections provide guidelines for the common areas where mistakes are most often made:
- Exception Management
- User Experience
- User Interface
Caching is one of the best mechanisms you can use to improve application performance and UI responsiveness. You can use data caching in the presentation layer to optimize data lookups and avoid network round trips, and to store the results of expensive or repetitive processes to avoid unnecessary duplicated processing. Consider the following guidelines when designing your caching strategy:
- Choose the appropriate location for your cache, such as in memory or on disk. If your application is deployed in Web farm, avoid using local caches that must be synchronized. In general, for Web and application farm deployments, consider using a transactional resource manager such as Microsoft SQL Server®, or a product that supports distributed caching such as the Danga Interactive "Memcached" technology or the Microsoft "Velocity" caching mechanism. However, if the variation between individual servers is not critical, or the data changes very slowly, in-memory caching may be appropriate.
- Consider caching data in a ready to use format when working with an in-memory cache. For example, use a specific object instead of caching raw database data. However, avoid caching volatile data as the cost of caching may exceed that of recreating or fetching the data again if it constantly changes.
- Do not cache sensitive data unless you encrypt it.
- Do not depend on data still being in your cache; it may have been removed. Also, consider that the cached data may be stale. For example, when conducting a business transaction, you may want to fetch the most recent data to apply to the transaction rather than use what is in the cache.
- Consider authorization rights for cached data. Only cache data for which you can apply appropriate authorization if users in different roles may access the data.
- If you are using multiple threads, ensure that all access to the cache is thread-safe.
For more information on caching techniques, see Chapter 17 "Crosscutting Concerns."
Handle long-running requests with user responsiveness in mind, as well as code maintainability and testability. Consider the following guidelines when designing request processing:
- Consider using asynchronous operations or worker threads to avoid blocking the UI for long-running actions in Windows Forms and WPF applications. In ASP.NET, consider using AJAX to perform asynchronous requests. Provide feedback to the user on the progress of the long running action. Consider allowing the user to cancel the long running action.
- Avoid mixing your UI processing and rendering logic.
- When making expensive calls to remote sources or layers, such as when calling Web services or querying a database, consider if it makes more sense to make these calls chatty (many smaller requests) or chunky (one large request). If the user requires a large volume of data to complete a task, consider retrieving just what is required for display and to get started, then incrementally retrieve the additional data on a background thread or as the user requires it (data paging and UI virtualization are examples of this approach). Consider using larger, chunky calls when the user does not have to wait for the call to complete.
Consider whether your application will be easier to develop and maintain if the presentation layer uses independent modules and views that are composed at run time. UI composition patterns support the creation of views and the presentation layout at run time. These patterns also help to minimize code and library dependencies that would otherwise force recompilation and redeployment of a module when the dependencies change. Composition patterns help you to implement sharing, reuse, and replacement of presentation logic and views. Consider the following guidelines when designing your UI composition strategy:
- Avoid dependencies between components. For example, use abstraction patterns when possible to avoid issues with maintainability. Consider patterns that support run-time dependency injection.
- Consider creating templates with placeholders. For example, use the Template View pattern to compose dynamic Web pages in order to ensure reuse and consistency.
- Consider composing views from reusable modular parts. For example, use the Composite View pattern to build a view from modular, atomic component parts. Consider decoupling for your application by using separate modules that can be added easily.
- Be cautious when using layouts generated dynamically at run time, which can be difficult to load and maintain. Investigate patterns and third-party libraries that support dynamic layout and injection of views and presentation at runtime.
- When communicating between presentation components, consider using loosely coupled communication patterns such as Publish/Subscribe. This will lower the coupling between the components and improve testability and flexibility.
Design a centralized exception management mechanism for your application that catches and manages unexpected exceptions (exceptions that you cannot recover from locally) in a consistent way. Pay particular attention to exceptions that propagate across layer or tier boundaries, as well as exceptions that cross trust boundaries. Consider the following guidelines when designing your exception management strategy:
- Provide user friendly error messages to notify users of errors in the application, but ensure that you avoid exposing sensitive data in error pages, error messages, log files, and audit files. Attempt to leave the application in a consistent state if possible, or consider terminating it if this is not possible.
- Ensure that you catch exceptions that will not be caught elsewhere (such as in a global error handler), and clean up resources and state after an exception occurs. A global exception handler that displays a global error page or an error message is useful for all unhandled exceptions. Unhandled exceptions generally likely indicate that the system is in an inconsistent state and may need to be gracefully shut down.
- Differentiate between system exceptions and business errors. In the case of business errors, display a user friendly error message and allow the user to retry the operation. In the case of system exceptions, check to see if an issue such as a service or database failure caused the exception, display a user friendly error message, and log the error message to assist in troubleshooting.
- Only catch exceptions that you can handle, and avoid the use of custom exceptions when not necessary. Do not use exceptions to control application logic flow.
For more information on exception management techniques, see Chapter 17 "Crosscutting Concerns."
Design your navigation strategy so that users can navigate easily through your screens or pages, and so that you can separate navigation from presentation and UI processing. Ensure that you display navigation links and controls in a consistent way throughout your application to reduce user confusion and to hide application complexity. Consider the following guidelines when designing your navigation strategy:
- Design toolbars and menus to help users find functionality provided by the UI.
- Consider using wizards to implement navigation between forms in a predictable way, and determine how you will preserve navigation state between sessions if this is necessary.
- Avoid duplication of logic for navigation event handlers, and avoid hard-coding navigation paths where possible. Consider using the Command pattern to handle common actions from multiple sources.
Good user experience can make the difference between a usable and unusable application. Perceived performance is much more important than actual performance and so expectation management and knowledge of the patterns of user interaction are essential. For example, users might not mind waiting longer for a page to load if they get feedback on when the page is likely to be loaded, and this wait time does not interfere with their activities. In other situations, a very short delay—even fractions of a second for some UI actions—can make the application feel unresponsive. Consider conducting usability studies, surveys, and interviews to understand what users require and expect from your application, and design to achieve an efficient UI with these results in mind. Consider the following guidelines when designing for user experience:
- Do not design overloaded or over complex interfaces. Provide a clear path through the application for each key user scenario, and consider using colors and noninvasive animations to draw the user's attention to important changes in the UI, such as state changes.
- Provide helpful and informative error messages, without exposing sensitive data.
- For actions that might take longer to complete, try to avoid blocking the user. At a minimum, provide feedback on the progress of the action, and consider if the user should be able to cancel the process.
- Consider empowering the user by providing flexibility and customization of the UI through configuration and, where appropriate, personalization.
- Consider how you will support localization and globalization, even if this is not a primary requirement in the initial design. Attempting to add support for localization and globalization once the design is complete can involve a great deal of rework and refactoring.
Design a suitable user interface to support your data input and data validation requirements. For maximum usability, follow the established guidelines defined by your organization, and the many established industry usability guidelines that are based on years of user research into input design and mechanisms. When choosing a layout strategy for your user interface, consider whether you will have a separate team of designers building the layout, or whether the development team will create the UI. If designers will be creating the UI, choose a layout approach that does not require code or the use of development focused tools. Consider the following guidelines when designing your user interface:
- Consider using a Separated Presentation pattern such as MVP to separate the layout design from interface processing. Use templates to provide a common look and feel to all of the UI screens, and maintain a common look and feel for all elements of your UI to maximize accessibility and ease of use. Avoid over complex layouts.
- Consider using forms-based input controls for data collection tasks, a document-based input mechanism for collecting more free form input such as text or drawing documents, or a wizard-based approach for more sequenced or workflow driven data collection tasks.
- Avoid using hard-coded strings, and using external resources for text and layout information (for example, to support right-to-left languages), especially if your application will be localized
- Consider accessibility in your design. You should consider users with disabilities when designing your input strategy; for example, implement text-to-speech software for blind users, or enlarge text and images for users with poor sight. Support keyboard-only scenarios where possible for users who cannot manipulate a pointing device.
- Take into account different screen sizes and resolutions, and different device and input types such as mobile devices, touch screens, and pen and ink—enabled devices. For example, with touch screen input you will typically use larger buttons with more spacing between them than you would in a UI designed only for mouse and keyboard input. When building a Web application, consider using Cascading Style Sheets (CSS) for layout. This will improve rendering performance and maintainability.
Designing an effective input and data validation strategy is critical for the security and correct operation of your application. Determine the validation rules for user input as well as for business rules that exist in the presentation layer. Consider the following guidelines when designing your input and data validation strategy:
- Input validation should be handled by the presentation layer, whilst business rule validation should be handled by the business layer. However, if your business and presentation layers are physically separated, business rule validation logic should be mirrored in the presentation layer to improve usability and responsiveness. This can be achieved using meta-data or by using common validation rule components in both layers.
- Design your validation strategy to constrain, reject, and sanitize malicious input. Investigate design patterns and third party libraries that can assist in implementing validation. Identify business rules that are appropriate for validation, such as transaction limits, and implement comprehensive validation to ensure that these rules are not compromised.
- Ensure that you correctly handle validation errors, and avoid exposing sensitive information in error messages. In addition, ensure that you log validation failures to assist in the detection of malicious activity.
For more information on validation techniques, see Chapter 17 "Crosscutting Concerns."
For the Microsoft platform, the following guidelines will help you to choose an appropriate implementation technology for the presentation layer. These guidelines also suggest common patterns that are useful for specific types of applications and technologies.
Consider the following guidelines when designing a mobile application:
- If you want to build full-featured connected, occasionally connected, or disconnected executable applications that run on a wide range of Microsoft Windows—based devices, consider using the Microsoft Windows Compact Framework.
- If you want to build connected applications that support a wide variety of mobile devices, or require Wireless Application Protocol (WAP), compact HTML (cHTML), or similar rendering formats, consider using ASP.NET for Mobile.
Rich Client Applications
Consider the following guidelines when designing a rich client application:
- If you want to build rich media and graphics capable applications, consider using Windows Presentation Foundation (WPF).
- If you want to build applications that are downloaded from a Web server and execute on a Windows client, consider using XAML Browser Applications (XBAP).
- If you want to build applications that are predominantly document-based, or are used for reporting, consider designing a Microsoft Office Business Application (OBA).
- If you want to take advantage of the extensive range of third party controls, and rapid application development tools, consider using Windows Forms. If you decide to use Windows Forms and you are designing a composite application, consider using the patterns & practices Smart Client Software Factory.
- If you decide to build an application using WPF, consider the following:
- For composite applications, consider using the patterns & practices Composite Client Application Guidance.
- Consider using the Presentation Model (Model-View-ViewModel) pattern, which is a variation of Model-View-Controller (MVC) tailored for modern UI development platforms where the View is the responsibility of a designer rather than a classic developer. You can achieve this by implementing DataTemplates over User Controls to give designers more control. Also, consider using WPF Commands to communicate between your View and your Presenter or ViewModel.
Rich Internet Applications
Consider the following guidelines when designing a Rich Internet Application (RIA):
- If you want to build browser-based, connected applications that have broad cross-platform reach, are highly graphical, and support rich media and presentation features, consider using Silverlight.
- If you decide to build an application using Silverlight, consider the following:
- Consider using the Presentation Model (Model-View-ViewModel) pattern as described earlier in this chapter.
- If you are designing an application that must last and change, consider using the patterns & practices Composite Client Application Guidance.
Consider the following guidelines when designing a Web application:
- If you want to build applications that are accessed through a Web browser or specialist user agent, consider using ASP.NET.
- If you decide to build an application using ASP.NET, consider the following:
- Consider using master pages to simplify development and implement a consistent UI across all pages.
- For increased interactivity and background processing, with fewer page reloads, consider using AJAX with ASP.NET Web Forms.
- If you want to include islands of rich media content and interactivity, consider using Silverlight controls with ASP.NET.
- If you want to improve the testability of your application, or implement a more clear separation between your application user interface and business logic, consider using the ASP.NET MVC Framework. This framework supports a model-view-controller based approach to Web application development.
For information on the patterns & practices Smart Client Software Factory and Composite Client Application Guidance, see "patterns & practices Offerings" later in this chapter.
Consider the following guidelines to maximize the performance of your presentation layer:
- Design your presentation layer carefully so that it contains the functionality required to deliver a rich and responsive user experience. For example, ensure that your presentation layer is able to validate user input in a responsive way without requiring cross-tier communication. This may require business layer data validation rules to be represented in the presentation layer, perhaps by using meta-data or shared components.
- Interaction between the presentation layer and the business or services layer of the application should be asynchronous. This avoids the possibility of high latency or intermittent connectivity adversely affecting the usability and responsiveness of the application.
- Consider caching data in the presentation layer that will be displayed to the user. For example, you can cache the historical information that is displayed in a stock ticker.
- In general, avoid maintaining session data or caching per-user data unless the number of users is limited, or the total size of the data relatively small. However, if users tend to be active for a while, caching per user data for short periods may be an appropriate technique. Be aware of affinity issues in Web or application farms when storing or caching session data or per user data.
- Always use data paging when querying for information. Do not rely on queries that may return an unbounded volume of data, and use a data page size that is appropriate for the amount of data you will display. Use client-side paging only when absolutely necessary.
- In ASP.NET, use view state cautiously because it increases the volume of data included in each round trip, and can reduce the performance of the application. Consider configuring pages to use read-only sessions, or to not maintain sessions at all, where this is appropriate.
Design Steps for the Presentation Layer
The following steps describe a suggested process for designing the presentation layer of your application. This approach will ensure that you consider all of the relevant factors as you develop your architecture. The steps are:
- Identify your client type. Choose a client type that satisfies your requirements and adheres to the infrastructure and deployment constraints of your organization. For instance, if your users are equipped with mobile devices, and will be connected intermittently to the network, a mobile client is probably the best choice. For information that will help you choose the appropriate type of client, see Chapter 20 "Choosing an Application Type."
- Choose your presentation layer technology. Identify the functionality for your UI and the presentation layer in general and choose a UI technology that meets these requirements and is available for the type of client you have chosen. At this point, if the available technologies are not suitable, you may need to reconsider your choice of client type. For information on the technologies available for each application type, see Appendix B "Presentation Technology Matrix."
- Design your user interface. Consider if you want your UI to be modular, and identify how you will enforce separation of concerns in your presentation layer. Consider separated presentation patterns such as Presentation Model, MVC, and MVP. Use the guidelines in the sections on Composition, Navigation, User Experience, and User Interface earlier in this chapter to ensure that you design a suitable UI that meets your requirements. For details of the types of components that you may choose to use in your design, see Chapter 11 "Designing Presentation Components."
- Determine your data validation strategy. Use data validation techniques to protect your system from untrusted input. Also, determine an appropriate strategy for exception handling and logging. For more details of implementing appropriate strategies for validation, exception handling, and logging see Chapter 17 "Crosscutting Concerns."
Determine your business logic strategy. Factor out your business logic to decouple it from your presentation layer code. This will improve the maintainability of your application, making it easier to modify your business logic without affecting the presentation layer. The technique you choose depends on the complexity of your application; the following are the common approaches:
- UI Validation. For simple applications where the business logic is used only to validate user input, you may decide to locate the business logic in the UI components. However, be careful not to mix any business logic not concerned with validation within your UI components.
- Business Process Components. For applications that are more complex, applications that support transactions, or applications that contain basic business logic that extends beyond UI validation, consider locating the business logic in separate components that are used by the UI components.
- Domain Model. For complex enterprise applications, where the business logic is shared among multiple applications, consider separating the business components into their own logical layer. This allows you to deploy the business layer onto a separate physical tier to improve scalability and support reuse by other applications.
- Rules Engine. In applications that must support complex validation, process orchestrations, and domain logic, consider placing your business logic in a rules engine such as Microsoft BizTalk® Server.
Determine your strategy for communication with other layers. If your application has multiple layers, such as a data access layer and a business layer, determine a strategy for communication between your presentation layer and other layers. If you have a separate business layer, your presentation layer will communicate with the business layer. If you do not have a business layer, your presentation layer will communicate directly with the data access layer. Use the following techniques to access other layers:
- Direct method calls. If the layer with which you are communicating is on the same physical tier as the presentation layer, you can make direct method calls.
- Web services. Use a Web service interface if you want to share the data access or business logic with other applications, if the business layer or data access layer are deployed on a separate tier from presentation layer, or if decoupling is important. Consider WCF using the TCP protocol if your business logic or data access logic will be consumed by the presentation layer within your intranet. Consider WCF using the HTTP protocol if your business logic or data access logic will be consumed by your presentation layer across the Internet. Consider asynchronous communication using WCF and message queuing if your business logic or data access logic performs long-running calls.
For more details of implementing appropriate communication strategies, see Chapter 18 "Communication and Messaging."
Relevant Design Patterns
Key patterns for the presentation layer are organized by categories as detailed in the following table. Consider using these patterns when making design decisions for each category.
Cache Dependency. Use external information to determine the state of data stored in a cache.
Page Cache. Improve the response time for dynamic Web pages that are accessed frequently, but change less often and consume a large amount of system resources to construct.
Composition and Layout
Composite View. Combine individual views into a composite representation.
Presentation Model (Model-View-ViewModel) pattern. A variation of Model-View-Controller (MVC) tailored for modern UI development platforms where the View is the responsibility of a designer rather than a classic developer.
Template View. Implement a common template view, and derive or construct views using this template view.
Transform View. Transform the data passed to the presentation tier into HTML for display in the UI.
Two-Step View. Transform the model data into a logical presentation without any specific formatting, and then convert that logical presentation to add the actual formatting required.
Exception Shielding. Prevent a service from exposing information about its internal implementation when an exception occurs.
Application Controller. A single point for handling screen navigation.
Front Controller. A Web only pattern that consolidates request handling by channeling all requests through a single handler object, which can be modified at run time with decorators.
Page Controller. Accept input from the request and handle it for a specific page or action on a Web site.
Command. Encapsulate request processing in a separate command object with a common execution interface.
Asynchronous Callback. Execute long-running tasks on a separate thread that executes in the background, and provide a function for the thread to call back into when the task is complete.
Chain of Responsibility. Avoid coupling the sender of a request to its receiver by giving more than one object a chance to handle the request.
For more information on the Page Cache pattern, see "Enterprise Solution Patterns Using Microsoft .NET" at http://msdn.microsoft.com/en-us/library/ms998469.aspx.
For more information on the Application Controller, Front Controller, Page Controller, Template View, Transform View, and Two-Step View patterns, see Fowler, Martin. Patterns of Enterprise Application Architecture. Addison-Wesley, 2002. Or at http://martinfowler.com/eaaCatalog/.
For more information on the Composite View and Presentation Model patterns, see "Patterns in the Composite Application Library" at http://msdn.microsoft.com/en-us/library/dd458924.aspx.
For more information on the Chain of Responsibility pattern, see “Patterns in Practice” at http://msdn.microsoft.com/en-us/magazine/cc546578.aspx.
For more information on the Command pattern, see Chapter 5, "Behavioral Patterns" in Gamma, Erich, Richard Helm, Ralph Johnson, and John Vlissides. Design Patterns: Elements of Reusable Object-Oriented Software. Addison Wesley Professional, 1995.
For more information on the Asynchronous Callback pattern, see "Creating a Simplified Asynchronous Call Pattern for Windows Forms Applications" at http://msdn.microsoft.com/en-us/library/ms996483.aspx.
For more information on the Exception Shielding and Entity Translator patterns, see "Useful Patterns for Services" at http://msdn.microsoft.com/en-us/library/cc304800.aspx.
patterns & practices Offerings
For more information on relevant offerings available from the Microsoft patterns & practices group, see the following resources:
- "Composite Client Application Guidance" at http://msdn.microsoft.com/en-us/library/cc707819.aspx.
- "Smart Client Software Factory" at http://msdn.microsoft.com/en-us/library/aa480482.aspx.
- "Web Client Software Factory" at http://msdn.microsoft.com/en-us/library/bb264518.aspx.
For more information, see the following:
- "Choosing the Right Presentation Layer Architecture" at http://msdn.microsoft.com/en-us/library/aa480039.aspx.
- "memcached" distributed memory object caching system at http://www.danga.com/memcached/.
- "Microsoft Inductive User Interface Guidelines" at http://msdn.microsoft.com/en-us/library/ms997506.aspx.
- "Microsoft Project Code Named Velocity" at http://msdn.microsoft.com/en-us/data/cc655792.aspx.
- "User Interface Text Guidelines" at http://msdn.microsoft.com/en-us/library/bb158574.aspx.
- "Design and Implementation Guidelines for Web Clients" at http://msdn.microsoft.com/en-us/library/ms978631.aspx.
- "Web Presentation Patterns" at http://msdn.microsoft.com/en-us/library/ms998516.aspx.