Designing Presentation Layers
J.D. Meier, Alex Homer,
Jason Taylor, Prashant Bansode, Lonnie Wall, Rob Boucher, Akshay Bogawat
The presentation layer represents the components that support displaying the user interface to end users and managing user interaction. This layer includes controls for user input and display, as well as component for organizing user interactions. The following
diagram shows how the presentation layer fits into a common application architecture.
Presentation Layer Components
- User interface (UI) components. User interface components provide a way for users to interact with the application. They render and format data for users. They also acquire and validate input data coming from the user.
- User process components. User process components synchronize and orchestrate user interactions. If you have a complicated user interface then separate user process components may be useful. Separating the user process components allows you reuse
your user interaction patterns in multiple user interfaces.
Use the following steps to help organize your thinking when designing the presentation layer:
- Identify your client type. Choose a client type that satisfies your requirements and adheres to the infrastructure and deployment constraints of your organization.
- Determine how you present data. Choose the data format for your presentation layer and decide how you will present the data in your User Interface (UI).
- Determine your data validation strategy. Use data validation techniques to protect your system from un-trusted input.
- Determine your business logic strategy. Factor your business logic to decouple business logic from presentation layer code.
- 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 communicating from your presentation layer to these other layers.
Use the following design principles when designing the presentation layer:
- Choose the appropriate UI technology. Determine if you will implement a rich client, a web client, or a rich internet application.
- Choose relevant patterns. Review the presentation layer patterns for proven solutions to common presentation problems.
- Design for separation of concerns. Use dedicated UI components to focus on rendering and display. Use dedicated presentation entities to manage the data required to present your views. Use dedicated UI process components to manage user interaction
- Consider human interface guidelines. Review guidelines that have been established for your organization. Review common user interface guidelines based upon the client type and technologies that you have chosen.
- Adhere to user-driven design. Before designing your presentation layer, understand your customer. Use surveys, usability studies and interviews to determine the best presentation design for your customer’s needs.
Presentation Layer Frame
||Caching volatile data
||Caching sensitive data
||Incorrect choice of caching store
||Cache synchronization in a web farm
||Assumption that needed data will be in the cache
||Failing to consider patterns and libraries that support dynamic layout and injection of views and presentation at runtime.
||Presentation classes have numerous dependencies on support classes and services vs considering patterns that support run-time dependency injection
||Failing to use the Pub/Sub Patterns to support events between components
||Failure to catch unhandled exceptions
||Failure to clean up resources and state after an exception
||Revealing sensitive information to the end user
||Improperly using exceptions to drive application logic
||Catching exceptions you don’t need to handle
||Using custom exceptions when they aren’t necessary
||Failure to design for usability
||Choosing the right layout style for web pages
||Overly complex layout
||Failure to choose appropriate layout components and technologies
||Duplication of logic to handle navigation events
||Failure to manage state with wizard navigation
||Defining entities that are not necessary
||Failure to implement serialization when necessary
||Blocking User interface for long running requests
||Mixing processing and rendering logic.
||Choosing the inappropriate pattern.
||Unfriendly error messages
||Lack of responsiveness
||Overloaded user interfaces
||Lack of user personalization
||Lack of user empowerment
||Creating custom components that are not necessary
||Failure to maintain state with MVC pattern
||Choosing appropriate UI components
|UI Process Components
||Implementing UI process components that are not necessary
||Choosing the correct design patterns
||Mixing business logic with UI process logic
||Mixing rendering logic with UI process logic
||Failure to validate input
||Reliance on client-side input validation
||Failure to handle validation errors properly
||Identifying business rules that are appropriate for validation
||Failure to log validation failures
Caching is one of the best mechanisms you can use to improve application performance and UI responsiveness. Use data caching to optimize data lookups and avoid network round trips. Cache the results of expensive or repetitive processing to avoid unnecessary
When designing caching, consider the following guidelines:
- Avoid distributed coherent caches
- Do not cache volatile data
- Do not cache sensitive data
- Consider using ready-to-use cache data when working with in-memory cache. For example using specific object instead of caching raw database data.
- Differentiate between cached data and state data.
- Evaluate between absolute expiration and sliding expiration
- Be deliberate while choosing time based expiration
- Consider automatically removing (scavenging) when working with memory based cache.
- Consider manually removing (explicit flushing) when working with disk based cache.
- Don’t depend upon data being in your cache.
- If you have persistent cache consider proactive loading.
- If you have in-memory cache avoid proactive loading, unless you have something expensive.
Consider whether your application could be developed and maintained with less effort if broken up into independent modules and views that could be easily composed at runtime. Composition patterns allow the dynamic loading of presentation logic as well as creation
of views and presentation layout at runtime. The patterns also allow one to remove code and library dependencies that would otherwise force a recompile and redeployment of a module when those dependencies changed. As a result, easy sharing, reuse and replacement
of presentation logic and views are possible.
When designing your exception management strategy, consider the following guidelines:
- Create dynamically loaded and reusable views to simplify design and improve performance and maintainability.
- Remove dependencies utilizing patterns like Dependency Injection thus allowing dynamic loading and easy replacement and modules.
- If you want to allow dynamically loaded modules communicate with each other consider the Publisher/Subscriber pattern.
- If you are composing dynamic web pages, consider the Template View pattern to improve reuse and consistency.
- If you are building a view from modular, atomic components, consider the Composite View pattern.
Design a centralized exception management approach so that exceptions are caught and thrown consistently in your application. Pay particular attention to exceptions that propagate past layer or tier boundaries, as well as exceptions that pass through trust
boundaries. Design for unhandled exceptions so they don’t result in application reliability issues or exposure of sensitive application information.
When designing your exception management strategy, consider the following guidelines:
- Design user friendly error messages.
- Avoid exposing sensitive data in error pages, error messages, log files and audit files.
- Implement a global exception handler including a global error page or error message for unhandled exceptions.
- Differentiate system exceptions from business errors.
- Only create custom exceptions if there is not a system exception that will meet your needs or you need to disambiguate from existing exceptions.
- Avoid driving application logic with exceptions.
Design a user input strategy based upon your application input requirements. Use forms-based input for simple data collection. Use document-based input when importing documents from the user’s file system. Use a wizard-based approach for input that is complex
or requires workflow.
When designing your input collection strategy, consider the following guidelines:
- Use forms-based input controls for normal data collection tasks.
- Use a document-based input mechanism for collecting office-style documents.
- Implement a wizard-based approach for more complex data collection or input that requires workflow.
- Determine your requirements for ink, speech or other device-based input types.
- Design with accessibility in mind.
Design your layout so that the layout of your application can be separated from the specific UI components and UI processing. When choosing a layout strategy, consider whether you will have designers building the layout or developers. If designers will be building
the layout, choose a layout approach that does not require coding or the use of development-focused tools.
When designing your layout strategy, consider the following guidelines:
- Choose a layout methodology such as table-based, css-based, using a designer, grid-based, or template based.
- Design with user personalization in mind.
- Use common layout for your UI to maximize accessibility and ease of use.
Design your navigation strategy so that users can easily navigate through your screens or pages and so that you can separate navigation from processing. Be careful to present a consistent navigation structure through your application to reduce user confusion
as well as application complexity.
When designing your navigation strategy, consider the following guidelines:
- Determine your screen navigation strategy. For instance, toolbars and menus, sitemap, master page.
- Separate navigation from processing.
- Determine how to preserve navigation state.
Use presentation entities to store the data that you will use in your presentation layer to manage your views. Presentation entities are not always necessary, only use them if your data-sets are complex enough or large enough that they need to be stored separately
from the UI controls.
When designing presentation entities, consider the following guidelines:
- Determine if you need presentation entities
- If you are working with data-bound controls, consider using DataSets, arrays or collections as your presentation entity format.
- If you want to map directly to business entities, use a custom class for your presentation entities.
Design your request processing with user responsiveness in mind as well as code maintainability and testability.
When designing request processing, consider the following guidelines:
- Be careful to not block the UI when making requests, especially long running requests.
- Do not mix your processing and rendering logic.
A focus on user experience can make the difference between a usable application and one that is unusable. Understand your users through usability studies, surveys, or interviews to understand how they approach your application and design with this in mind.
When designing user experience, consider the following guidelines:
- Keep the user perspective in mind when designing error messages.
- Focus on UI responsiveness.
- Do not design overloaded or overly complex interfaces. Make a clear path through the application for each key user scenario.
- Design for user personalization.
- Design for user empowerment. Allow the user to control how they interact with the application and how it displays data to them.
UI components are the controls and components used to display information from the user and accept user input. Be careful not to create custom controls unless it is necessary for specialized display or data collection.
When designing UI components, consider the following guidelines:
- In Windows Forms and Compact Framework applications, store UI state locally as entities or individual values.
- In ASP.NET applications, allow ASP.NET to manage state for UI controls and store UI state in the ViewState, Session, or Application objects depending on the scope required.
- In ASP.NET Mobile applications, allow ASP.NET to store state in the user's Session to minimize impact on the device.
- Take advantage of the data-binding features in the controls you use to create the user interface.
- Create custom controls or use third party controls for specialized display and data collection tasks.
UI Processing Components
UI process components synchronize and orchestrate user interactions. UI processing components are not always necessary. Only create them if you need to do significant processing in the presentation layer that must be separated from the UI controls. Be careful
not to mix business or display logic into the process components, they should be focused on organizing user interactions with your UI.
When designing UI processing components, consider the following guidelines:
- Choose relevant patterns, such as MVC, supervising controller, or passive view.
- Decouple the rendering and display from processing that must occur in the presentation layer.
- Avoid including business rules in the UI processing components. These belong in the business layer.
- Where the UI requires complex processing, use separate UI process components to decouple the processing from the UI.
- Where the UI requires workflow support, create separate workflow components that use a workflow system such as Windows Workflow or a custom mechanism.
Designing and effective input and data validation is critical to the security of your application. Determine the validation rules for user input as well as for business rules that exist in the presentation layer. Don’t rely on client-side validation for security
When designing your input and data validation strategy, consider the following guidelines:
- Validate all data input client-side where possible to improve interactivity and reduce errors caused by submitting invalid data.
- Do not rely on client side validation. Use server-side validation to constrain input for security purposes and to make security-related decisions.
- Centralize your validation approach, if it could be re-used.
- Constrain, reject, and sanitize your input.
- Use the built-in validation controls where possible.
- Use the Enterprise Library Validation Application Block when validation rules must be stored in configuration.
|UI Processing Components
||Model View Controller (MVC)
- Cache Dependency – Uses external information to determine the state of data stored in a cache.
- Composite View – Combine individual views into a composite representation.
- Dependency Injection – Use a base class or interface to define a shared abstraction that can be used to inject object instances into components that interact with the shared abstraction interface.
- Exception Shielding – Used to filter exception data that should not be exposed to external systems or users.
- Front Controller – The Front Controller consolidates all requests handling by channeling requests through a single handler object, which can be modified at runtime with decorators.
- MVC – Separate the data from the user interface and the user input processing.
- Page Cache – Improve the response time by using a page cache for dynamic Web pages that are accessed frequently, but change less often and consume a large amount of system resources to construct.
- Page Controller – Accept input from the page request, handle a request for a specific page or action on a Web site.
- Passive View – Reduce the view to the absolute minimum by allowing the controller to not only process user input but also maintain responsibility for updating the view.
- Supervising Controller – A variation on MVC in which the controller handlers complex logic, especially coordinating between views, but the view is responsible for simple view-specific logic.
- Template View – Implement a common template view, derive or construct views using the template view.
- Transform View – Transform the data passed to the presentation tier to HTML to be displayed on UI.
- Two-Step View** – Transform the model data into a logical presentation without any specific formatting and then convert that logical presentation with the actual formatting needed.
Use the following guidelines for specific technology areas.
- Use the Windows Compact Framework for full-featured connected, occasionally-connected, and disconnected applications.
- Use ASP.NET Mobile Forms and Mobile Controls for connected applications that require WAP, cHTML, or similar rendering formats.
- Use Silverlight for connected applications that require rich media support.
Rich Client Applications
- Use Windows Forms for good performance, interactivity, and design support in Visual Studio.
- Use Windows Forms combined with WPF User Controls for applications that require islands of rich media support.
- Use WPF for applications that are highly graphical and support rich media and presentation features.
- Use XAML Browser Applications (XBAP) for applications that are downloaded from a Web server and then execute on the client.
Rich Internet Applications (RIA)
- Use Silverlight for connected browser-based applications that are highly graphical and support rich media and presentation features.
- Use ASP.NET for connected applications exposed through a Web browser or specialist user agent.
- Use ASP.NET with AJAX for connected Web applications that require increased interactivity or background processing.
- Use ASP.NET with Silverlight controls for connected Web applications that include islands of rich media content and interactivity.
- Use the ASP.NET MVC Framework to implement a control-centric model with separate controllers and improved testability.