Rich Client Archetype
J.D. Meier, Alex Homer, David Hill, Jason Taylor, Prashant Bansode, Lonnie Wall, Rob Boucher Jr, Akshay Bogawat
- Define a rich client application.
- Understand key scenarios where rich client applications would be used.
- Understand components found in a rich client application.
- Learn about design considerations for rich client applications.
- Understand deployment scenarios for rich client applications.
- Learn the key patterns and technology considerations for designing rich client applications.
Rich client user interfaces (UIs) can provide high-performance, interactive, and rich user experiences for applications that must operate in stand-alone, connected, occasionally connected, and disconnected scenarios. Windows Forms, Windows Presentation Foundation (WPF), and Microsoft® Office Business Application (OBA) development environments and tools are available that allow developers to quickly and easily build rich client applications.
While these technologies can be used to create stand-alone applications, they can also be used to create applications that run on the client machine but communicate with services exposed by other layers (both logical and physical) that expose operations the client requires. These operations may include data access, information retrieval, searching, sending information to other systems, backup, and related activities.
Figure 1 shows an overall view of typical rich client architecture, and identifies the components usually found in each layer. Figure 1 Overall view of typical rich client architecture
Rich client applications can range from fairly thin interfaces that overlay business layers and service layers to complex applications that perform most of the processes themselves and only communicate with other layers to consume or send back information. An example is the difference between an application such as a File Transfer Protocol (FTP) client that depends on a remote server to provide all of the data for display, and an application such as Microsoft Office Excel® that performs complex local tasks, stores state and data locally, and only communicates with remote servers to fetch and update linked data.
Therefore, the design and implementation of a rich client varies a great deal. However, in terms of the presentation layer and UI, there are some common approaches to good architectural design. Most of these are based on well-known design patterns. Many of these patterns encourage the use of separate components within the application that reduce dependencies, make maintenance and testing easier, and promote reusability.
Some rich client applications are effectively stand-alone applications, and rely only on data retrieved and sent back to other layers of the application and to other applications. These types of rich clients may contain their own business layers and data access layers. They may also expose business and data services for other applications to use. The guidelines for the business and data layers in such applications are the same as those discussed generally for all applications.
A rich client application generally contains presentation layer components, which include UI components and UI processing components; business layer components, which include business workflow, business processing, business entity components, and, optionally, a façade; and data layer components, which include data access, data helper/utility, and service agent components. The following list describes each of the component types in more detail:
- User interface (UI) components. User interface components provide a way for users to interact with the application. They render and format data for display to users, and acquire and validate data that users enter.
- User process components. To help synchronize and orchestrate these user interactions, it can be useful to drive the process using separate user process components. This avoids hard-coding the process flow and state-management logic in the UI elements themselves, and the same basic user interaction patterns can be reused by multiple UIs.
- Business components. Business components implement the business logic of the application. Regardless of whether a business process consists of a single step or an orchestrated workflow, your application will probably require components that implement business rules and perform business tasks.
- Business workflows. After the required data is collected by a user process, the data can be used to perform a business process. Many business processes involve multiple steps that must be performed in the correct order and orchestrated. Business workflows define and coordinate long-running, multi-step business processes, and they can be implemented using business process management tools.
- Business entity components. Business entities are used to pass data between components. The data represents real-world business entities, such as products or orders. The business entities that are used internally in the application are usually data structures, such as DataSets, DataReaders, or Extensible Markup Language (XML) streams, but they can be implemented as custom object-oriented classes that represent the real-world entities your application has to work with, such as a product or an order.
- Application façade (optional). A façade is used to combine multiple business operations into single message-based operation. You might access the application façade from the presentation layer by using a range of communication technologies.
- Data access logic components. Data access components abstract the logic necessary to access your underlying data stores. Doing so centralizes data access functionality and makes it easier to configure and maintain.
- Data Helpers/utilities. Implement data helpers for centralizing generic data access functionality such as managing database connections and caching data. You can design data source–specific helper components to abstract the complexity of accessing the database. Avoid adding any business logic to the helper components.
- Service agents. When a business component must use functionality provided in an external service, you might need to provide some code to manage the semantics of communicating with that particular service. Service agents isolate the idiosyncrasies of calling diverse services from your application, and can provide additional services such as basic mapping between the format of the data exposed by the service and the format your application requires.
When designing a rich client application, the goal of a software architect is to choose an appropriate technology and design a structure that minimizes complexity by separating tasks into different areas of concern. The design should meet the requirements for the application in terms of performance, security, reusability, and ease of maintenance.
Consider the following guidelines when designing rich client applications:
- Choose an appropriate technology based on application requirements. Technologies include Windows Forms, Windows Presentation Foundation (WPF, XAML Browser Applications (XBAP), and Office Business applications (OBA).
- Separate presentation logic from interface implementation. Design patterns such as Model-View-Controller (MVC) and Supervising Controller separate the UI rendering from UI processing, which eases maintenance, promotes reusability, and improves testability.
- Identify the presentation tasks and presentation flows. This will help you to design each screen and each step in multi-screen or Wizard processes.
- Design to provide a suitable and usable interface. Take into account features such as layout, navigation, choice of controls, and localization to maximize accessibility and usability.
- Extract business rules and other tasks not related to the interface. A separate business layer should handle tasks not directly related to presentation, and not related to collecting and handling user input.
- Reuse common presentation logic. Libraries that contain templates, generalized client-side validation functions, and helper classes may be reusable in several applications.
- Loosely couple your client from any remote services it uses. Use a message-based interface to communicate with services located on separate physical tiers.
- Avoid tight coupling to objects in other layers. Use the abstraction provided by common interface definitions, abstract base classes, or messaging when communicating with other layers of the application. For example, implementing the Dependency Injection and Inversion of Control patterns can provide a shared abstraction between layers.
- Reduce round trips when accessing remote layers. Use coarse-grained methods and execute them asynchronously if possible to avoid blocking or freezing the UI.
Rich Client Frame
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 table lists the common issues for each category where mistakes are most often made.Table 1 Common rich client design issues
|Category ||Key issues|
|Communication ||Choosing the wrong communication protocols and technology |
| ||Using synchronous communication methods when asynchronous methods could provide better responsiveness |
| ||Failing to properly detect and manage disconnected or occasionally connected scenarios |
| ||Using fine-grained “chatty” interfaces across physical tiers |
|Composition ||Choosing an inappropriate composition technology |
| ||Not managing auto-update and versioning of composable components |
| ||Failing to take advantage of appropriate templates and data-binding technologies |
| ||Failing to take into account personalization requirements |
|Configuration Management ||Failing to manage configuration information correctly |
| ||Not securing sensitive configuration information |
| ||Failing to identify the appropriate configuration options and information |
| ||Failing to take into account Group Policy overrides |
|Data Access ||Failing to design support for the appropriate data format, such as custom objects, Table Module, Domain Model, Data Transfer Objects, or DataSets |
| ||Failing to manage offline data access, concurrency, and subsequent synchronization correctly |
| ||Not minimizing data returned from remote services and layers |
| ||Failing to support large sets of data when required |
|Exception Management ||Not planning a strategy for handling and managing exceptions |
| ||Raising exceptions when not appropriate |
| ||Failing to sanitize exceptions and remove sensitive information |
| ||Not implementing appropriate logging and auditing functionality |
| ||Failing to support administrative and remote management and error-reporting requirements |
| ||Controlling application flow with exceptions |
|State Management ||Failing to store and manage UI state information correctly |
| ||Failing to cache state where appropriate |
| ||Choosing an inappropriate cache store |
| ||Failing to protect and secure sensitive state information |
| ||Failing to support transactions where required |
|Workflow ||Failing to design and implement an appropriate workflow or viewflow mechanism |
| ||Not implementing error and exception management for workflows and viewflows |
Rich clients can communicate with other layers of the application and with other services by using a variety of protocols and methods. These may include Hypertext Transfer Protocol (HTTP) requests, Simple Mail Transfer Protocol (SMTP) e-mail messaging, SOAP Web service messages, Simple Network Time Protocol (SNTP) time synchronization packets, Distributed Component Object Model (DCOM) for remote components, and many other Transmission Control Protocol (TCP)/Internet Protocol (IP)–based standard or custom communication protocols. Alternatively, if the client application is located on the same physical tier as the business layer, you should use object-based interfaces to interact with the business layer.
Consider the following guidelines when designing a communication strategy:
- When communicating with business layers, services, and components on a remote physical tier, use a message-based protocol when possible. This gives you a more natural way to make asynchronous calls to avoid locking the presentation layer and support load-balanced and failover server configurations.
- When communicating with business layers, services, and components on a remote physical tier, use coarse-grained interfaces to minimize network traffic and maximize performance.
- Where practical, enable offline processing for the application. Detect connection state. When disconnected, cache information locally and then re-synchronize when communication is re-enabled. Consider holding application state and data locally in a persistent cache to allow disconnected start-ups and a shutdown/restart without information loss.
- To protect sensitive information and communication channels, consider using Internet Protocol Security (IPSec) and Secure Sockets Layer (SSL) to secure the channel, encryption to protect data, and digital signatures to detect data tampering.
- If the application must consume or send large sets or amounts of data, consider the potential performance and network impact. Choose more efficient communication protocols such as TCP, using compression mechanisms to minimize the data payload size for message-based protocols such as SMTP and SOAP, or custom binary formats when the application does not need to support open communication standards.
Complex UIs are common in business applications. Users may open several forms to perform specific tasks, and work with data in a range of different ways. To maximize extensibility and maintainability of the application, consider implementing the interface using the Composition design pattern, where the UI consists of separate modules or forms loaded dynamically at run time. Users can open and close forms as required, and the application can maximize performance and reduce start-up delays by loading these forms only when required. Also consider how you can support personalization for users, so that they can modify the layout and content to suit their own requirements.
Consider the following guidelines when designing a composition strategy:
- Based on functional specifications and requirements, identify the appropriate types of interface components you require. For example, possible components include Windows Forms, WPF forms, Office-style documents, user controls, or custom modules.
- Be careful with dependencies between components. Use abstraction patterns when possible to avoid issues with maintainability.
- Identify an appropriate composition mechanism. You may decide to use a composition framework or built-in features of your development environment such as user controls or document panels.
- Consider composing views from reusable modular parts. For example, use the Composite View pattern to build a view from modular, atomic component parts.
- If you need to allow communication between presentation components, consider implementing the Publish/Subscribe pattern. This will lower the coupling between the components and improve testability.
Rich client applications will usually require configuration information loaded at startup, and sometimes during execution. This information may be network or connection information, user settings, part of the UI business rules, or general display and layout settings. You may decide to store some or all of this information locally, or download it from other layers when the application starts. You may also need to persist changes to the information as the application runs or when it ends; for example, storing user preferences, layout settings, and other UI data in a user’s local profile.
Consider the following guidelines when designing a configuration management strategy:
- Determine what configurable data may change in the life of your application; for example, file locations, developer versus production settings, logging, assembly references, and contact information for notifications.
- Choose local or centralized storage locations. User-managed data should be stored locally. Global application settings should be in a central location and perhaps downloaded locally for performance reasons.
- Identify sensitive configuration information and implement a suitable mechanism for protecting it during transit over the network, when persisted locally, and even when stored in memory.
- Take into account any global security policies that might affect or override local configurations.
Rich client applications will usually access data stored on a remote physical tier, as well as data stored on local physical layers and even on the local machine. Data access often has a significant impact on performance, and is the most obvious factor in the user’s perception of an application and its usability and responsiveness. You should aim to maximize performance of data-access routines and data transmission across tiers. You must also design the application with regard to the types of data it will use, and the way that this data is exposed from other layers of the application.
Consider the following guidelines when designing a data-access strategy:
- If the client application cannot handle the data in the exposed format, you must implement a translation mechanism that converts it. However, this will have an impact on performance.
- If the client will consume very large amounts of data, consider chunking these and loading them asynchronously into a local cache to improve performance. You will have to handle inconsistencies between the local copy and the original data using methods such as time stamps or events.
- Whenever possible, load data asynchronously so that the UI is still responsive while the data is loading. However, you must also be aware of conflicts that might occur if the user attempts to interact with the data before loading is complete, and design the interface to protect against errors arising from this.
- In occasionally connected scenarios, monitor connectivity and implement a service dispatcher mechanism to support batch processing in order to allow users to perform multiple updates to data.
- Determine how you will detect and manage concurrency conflicts that arise when multiple users attempt to update the data store. Explore optimistic and pessimistic concurrency models.
All applications and services are subject to the occurrence of errors and exceptions, and you must implement a suitable strategy for detecting and managing these errors and exceptions. In a rich client application, you will usually need to notify the user. In addition, for anything other than trivial UI errors such as validation messages, you should consider logging errors and exceptions for use by management tools and monitoring systems.
Consider the following guidelines when designing an exception-management strategy:
- Identify the errors and exceptions that are likely to arise within the application, and identify which of these require only user notification. Errors such as validation failures are usually only notified locally to the user. However, errors such as repeated invalid logon attempts or detection of malicious data should be logged and administrators notified. All execution exceptions and application failures should be logged and optionally administrators notified.
- Identify an overall strategy for handling exceptions. This may involve actions such as wrapping exceptions with other application-specific or custom exceptions that contain additional data to assist in resolving failures, or replacing exceptions to prevent exposure of sensitive information. Also, implement a mechanism for detecting and logging unhandled exceptions. A framework for managing exceptions may be useful for these tasks.
- Determine how you will store exception information, how you will pass it to other layers of the application if required, and how you will notify administrators. Consider using a monitoring tool or environment that can read events from the local machine and present a view of the application state to administrators.
- Ensure that you sanitize exception information that is exposed to users in order to prevent sensitive information from being displayed or stored in log and audit files. If necessary, encrypt information and use secure channels to communicate exceptions and errors to other physical tiers of the application.
Rich clients, whether designed to run offline or only when connected, will generally store state information. This may include user settings, configuration information, workflow information, business rule values, and data that the UI is displaying and the user is editing. The application must be able to save this data, access it as required, and handle conflicts, restarts, and connection status changes.
Consider the following guidelines when designing a state-management strategy:
- Determine the state information that the application must cache, including estimates of the size, the frequency of changes, and the processing or overhead cost of re-creating or re-fetching the data. These factors will help you decide type of state mechanism to use.
- If you have large volumes of data, consider using a local disk-based mechanism.
- If the application requires data to be available when it starts up, use a persistent mechanism such as isolated storage or a disk file.
- When storing sensitive data, ensure that you implement the appropriate level of protection by using encryption and/or digital signatures.
- Consider at what granularity you need to maintain state information. For instance, determine the state information that applies to all users of an application versus the information that applies only to specific users or roles
Some rich client applications require viewflow or workflow support to enable multi-stage operations or Wizard-style UI elements. You can implement these features using separate components or custom solutions, or you can take advantage of a framework such as Windows Workflow (WF) or, for document-based interfaces, Microsoft Office SharePoint® Server (MOSS).
Consider the following guidelines when designing a workflow strategy:
- Use workflow within business components for operations that involve multi-step or long-running processes.
- For simple workflow and viewflow requirements, it is usually sufficient to use custom code based on well-known patterns such as Use Case Controller and ViewFlow.
- For more complex workflow and viewflow requirements, consider using a platform provided workflow engine such as WF.
- Consider creating separate components to implement your workflow and viewflow tasks. This reduces dependencies and makes it easier to swap out components as requirements change.
- Consider how you will capture, manage, and display errors in workflows.
- Identify how you will handle partially completed tasks, and whether it is possible to recover from a failure and continue the task or whether you need to restart the process.
Rich client applications often implement the presentation layer for business applications. Presentation layer is the parts of the application that the user sees and interacts with, and must therefore satisfy many requirements. These requirements encompass general factors such as usability, performance, design, and interactivity. A poor UI can have a negative impact on a business application that performs well in all other respects.
Consider the following guidelines when designing the presentation features of your application:
- Investigate how you can separate data used by the UI, which may be cached or stored locally, from the UI itself. This makes it easier to update parts of the application, allows developers and designers to work separately on the components, and improves testability.
- Take advantage of data-binding capabilities to display data whenever possible, especially for tabular and multi-row data presentation. This reduces the code required, simplifies development, and reduces coding errors. It can also automatically synchronize data in different views or forms. Use two-way binding where the user must be able to update the data.
- Consider how you will display documents in an Office document–style interface, or when displaying document content or HTML in other UI elements. Ensure that the user is protected from invalid and malicious content that might reside in documents.
- Implement command and navigation strategies and mechanisms that are flexible and can be updated easily. Consider implementing well-known design patterns such as Command, Publish/Subscribe, and Observer to decouple commands and navigation from the components in the application and improve testability.
- Ensure that the application can be globalized and localized to all geographical and cultural scenarios where it may be used. This includes changing the language, text direction, and content layout based on configuration or auto-detection of the user’s culture.
Business Layer Considerations
In most business scenarios, rich client applications will access data or information located outside the application. While the nature of the information will vary, it is likely to be extracted from a business system. A rich client application may act as the presentation layer for a business application, or may include a business layer, data access layer, and service agents that communicate with remote services. You should design the rich client interface using the accepted principles for designing presentation layers. In addition, to maximize performance and usability, you might consider locating some of the business-processing tasks on the client.
Consider the following guidelines when designing interaction with business and service layers:
- Identify the business layers and service interfaces that the application will use. Import the interface definitions and write code that accesses the business layer service functions using the interfaces. This helps to minimize coupling between the client and the business layer and services.
- If your business logic does not contain sensitive information, consider locating some of the business rules on the client to improve performance of the UI and the client application.
- If your business logic does contain sensitive information, you should locate the business layer on a separate tier.
- Consider how the client will obtain information required to operate business rules and other client-side processing, and how it will update the business rules automatically as requirements change. You might want to have the client obtain business rule information from the business layer when it starts up.
It is vital to minimize maintenance cost and effort for all applications and components. Rich client applications are usually located remotely from the main servers of an application, and are subsequently more difficult to maintain than server-installed services and components. You should implement mechanisms that reduce maintenance liabilities. Issues to consider include deployment, updates, patches, and versioning.
Consider the following guidelines when designing a maintainability strategy:
- Implement a suitable mechanism for manual and/or automatic updates to the application and its components. You must take into account versioning issues to ensure that the application has consistent and interoperable versions of all the components it uses.
- Choose an appropriate deployment approach based on the environment in which your application will be used. For example, you might need an installation program for applications that are publically available, or you might be able to use system tools to deploy applications within a closed environment.
- Design the application so that components are interchangeable where possible, allowing you to change individual components depending on requirements, run-time scenarios, and individual user requirements or preferences.
- Implement logging and auditing as appropriate for the application to assist administrators and developers when debugging the application and solving run-time problems.
- Design to minimize dependencies between components and layers so that the application can be used in different scenarios where appropriate, and to reduce the possibility of changes to other layers affecting the client application.
Security encompasses a range of factors and is vital in all types of applications. Rich client applications must be designed and implemented to maximize security, and—where they act as the presentation layer for business applications—must play their part in protecting and securing the other layers of the application. Security issues involve a range of concerns, including protecting sensitive data, user authentication and authorization, guarding against attack from malicious code and users, and auditing and logging events and user activity.
Consider the following guidelines when designing a security strategy:
- Determine the appropriate technology and approach for authenticating users, including support for multiple users of the same rich client application instance. You should consider how and when to log on users, whether you need to support different types of users (different roles) with differing permissions (such as administrators and standard users), and how you will record successful and failed logons. Take into account the requirements for disconnected or offline authentication where this is relevant.
- Consider a single sign-on (SSO) or federated authentication solution if users must be able to access multiple applications with the same credentials or identity. You can implement a suitable solution by registering with an external agency that offers federated authentication, use certificate systems, or create a custom solution for your organization.
- Consider the need to validate inputs, both from the user and from sources such as services and other application interfaces. You might need to create custom validation mechanisms, or you might be able to take advantage of validation frameworks. The Microsoft Visual Studio® Windows Forms development environment contains validation controls. The Enterprise Library Validation Application Block provides comprehensive features for validation in the UI and in the business layer. Irrespective of your validation choice, remember that you must always validate data when it arrives at other layers of the application.
- Consider how you will protect data stored in the application and in resources such as files, caches, and documents used by the application. Encrypt sensitive data where it might be exposed, and consider using a digital signature to prevent tampering. In maximum-security applications, consider encrypting volatile information stored in memory. Also, remember to protect sensitive information that is sent from the application over a network or communication channel.
- Consider how you will implement auditing and logging for the application, and what information to include in these logs. Remember to protect sensitive information in the logs using encryption, and optionally use digital signatures for the most sensitive types of information that is vulnerable to tampering.
Data Handling Considerations
Application data can be made available from server-side applications through a Web service. Cache this data on client to improve performance and enable offline usage. Rich client applications can also use local data.
Types of Data
Data use by rich client applications falls into two categories:
- Read-only reference data. This is data that is not changed by the client, and is used by the client for reference purposes. Store reference data on the client to reduce the amount of data interchange between the client and the server in order to improve the performance of your application, enable offline capabilities, provide early data validation, and generally improve the usability of your application. In cases where the client does change the data for local purposes, there is no need to keep track of client-side changes to the data on the server.
- Transient data. This is data that is changed on the client as well as the on server. One of the most challenging aspects of dealing with transient data in rich client applications is that it can generally be modified by multiple clients at the same time. You must keep track of any client-side changes made to transient data on the client.
Rich clients often need to cache data locally, whether it is read-only reference data or transient data. Caching data can improve performance in your application and provide the data necessary to work offline.** To enable data caching, rich Client applications should implement some form of caching infrastructure that can handle the data caching details transparently. The common types of caching are:
- Short-term data caching. Data is not persistent, so the application cannot run offline.
- Long-term data caching. Caching data in a persistent medium, such as isolated storage or the local file system, allows the application to work when there is no connectivity to the server. Rich client applications should differentiate between data that has been successfully synchronized with the server and data that is still tentative.
Changes to the data held on the server can occur before any client-side changes are synchronized with the server. You must implement a mechanism to ensure that any data conflicts are handled appropriately when the data is synchronized, and that the resulting data is consistent and correct.
Approaches for handling data concurrency are:
- Pessimistic concurrency.** Pessimistic concurrency allows one client to maintain a lock over the data to prevent any other clients from modifying the data until the client’s own changes are complete.
- Optimistic concurrency.** Optimistic concurrency does not lock the data. The original data is then checked against the current data to see if it has been updated since it was last retrieved.
Using ADO.NET DataSets to Manage Data
The ADO.NET DataSet
helps clients to work with data while offline. DataSets
can keep track of local changes made to the data, which makes it easier to synchronize the data with the server and reconcile data conflicts. DataSets
can also be used to merge data from different sources.
Windows Forms Data Binding
Windows Forms data binding supports bidirectional binding that allows you to bind a data structure to a UI component, display the current data values to the user, allow the user to edit the data, and then automatically update the underlying data using the values entered by the user.
Data binding can be used to:
- Display read-only data to users.
- Allow users to update data within the UI.
- Provide master-detail views of data.
- Allow users to explore complex related data items.
- Provide lookup table functionality, allowing the UI to display user-friendly names for data items instead of data row key values.
Offline/Occasionally Connected Considerations
An application is occasionally connected if, during unspecified periods, it cannot interact with services or data over a network in a timely manner. Occasionally connected rich client applications are capable of performing work when not connected to a networked resource, and can update the networked resources in the background when a connection is available.
Offline/Occasionally Connected Design Strategies:
Consider the following two approaches when designing for an occasionally connected scenario:
- Data-centric. Applications that use the data-centric strategy have a relational database management system (RDBMS) installed locally on the client, and use the built-in capabilities of the database system to propagate local data changes back to the server, handle the synchronization process, and detect and resolve any data conflicts.
- Service-oriented. Applications that use the service-oriented approach store information in messages, and arrange these messages in queues while the client is offline. After the connection is reestablished, the queued messages are sent to the server for processing.
Principles of Occasionally Connected Applications
Consider the following guidelines for designing occasionally connected applications:
- Favor asynchronous communication when interacting with data and services over a network.
- Minimize or eliminate complex interactions with network-located data and services.
- Add data-caching capabilities. Ensure that all of the data necessary for the user to continue working is available on the client when it goes offline.
- Design a store-and-forward mechanism where messages are created, stored while disconnected, and eventually forwarded to their respective destinations when a connection becomes available. The most common implementation of store-and-forward is a message queue.
- Determine how to deal with stale data, and how to prevent your rich client from using stale data.
There are several options for deployment of rich client applications. You might have a stand-alone application where all of the application logic, including data, is deployed on the client machine. Another option is client/server, where the application logic is deployed on the client and the data is deployed on a database tier. Finally, there are several n
-tier options where an application server contains part of the application logic.
Figure 2 illustrates a stand-alone deployment where all of the application logic and data is deployed on the client. Figure 2 Stand-alone deployment for a rich client application
In a client/server deployment, all of the application logic is deployed on the client and the data is deployed on a database server, as shown in Figure 3. Figure 3 Client/server deployment for a rich client application
In an n
-tier deployment, you can place presentation and business logic on the client, or only the presentation logic on the client. Figure 4 illustrates the case where the presentation and business logic are deployed on the client. Figure 4 N-tier deployment with the business layer located on the client tier
Figure 5 illustrates the case where the business and data access logic are deployed on an application server. Figure 5 N-tier deployment with the business layer located on the application tier
Deploying Rich Client Applications
Several options are available for deploying a rich client application to a physical machine. Each has specific advantages and liabilities, and you should research the options to ensure that the one you choose is suitable for the target environments in which your application will execute.
The options are the following:
- No-touch deployment. The application executable is downloaded to the assembly download cache on the user’s machine and executes in an environment that has constrained security settings.
- No-touch deployment with an application update stub. The application is automatically updated when the server-based version changes.
- XCOPY deployment. If no registry settings or component registration is required, the executable can be copied directly to the client machine hard disk.
- Windows Installer (.MSI) package. This is a comprehensive setup program that can install components, resources, registry settings, and other artifacts required by the application.
- XBAP (XML Browser Application) package. The application is downloaded through the browser and runs in a constrained security environment on the machine. Updates can be pushed to the client automatically.
It is important to know the deployment approach you will use for the application during the design phase, as this can limit the capabilities for deploying and installing artifacts that make up the application.
Consider the following deployment guidelines when designing a rich client application:
- Know your target physical deployment environment early, from the planning stage of the life cycle.
- Clearly communicate the environmental constraints that drive software design and architecture decisions.
- Clearly communicate the software design decisions that require certain infrastructure attributes.
Table 2 Pattern map
|Category ||Relevant patterns|
|Communication ||Asynchronous Callback |
| ||Gateway / Service Gateway |
| ||Service Locator |
| ||Service Agent and Proxy |
| ||Service Interface |
|Composition ||Composite View |
| ||Template View |
| ||Two-Step View |
| ||View Helper |
|Configuration Management ||Provider |
|Data Services ||Domain Model |
| ||Entity Translator |
| ||Data Transfer Object |
|Exception Management ||Exception Shielding |
|State Management ||Context Object |
|Workflow ||View Flow |
| ||Work Flow |
- 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.
- Composite View.** Combine individual views into a composite view
- Context Object.** An object used to manage the current execution context.
- Data Transfer Object.** An object that stores the data transported between processes, reducing the number of method calls required.
- Domain Model.** A set of business objects that represents the entities in a domain and the relationships between them.
- Entity Translator.** An object that transforms message data types into business types for requests, and reverses the transformation for responses.
- Exception Shielding.** Prevent a service from exposing information about its internal implementation when an exception occurs.
- Gateway.** Provide access to an external system through a common abstract interface so that consumers are not required to understand the external system interface.
- Provider.** Implement a component that exposes an API that is different from the client API in order to allow any custom implementation to be seamlessly plugged in.
- Service Interface. A programmatic interface that other systems can use to interact with the service.
- Service Locator. Centralize distributed service object lookups, provide a centralized point of control, and act as a cache that eliminates redundant lookups.
- Template View. Implement a common template view, and derive or construct views using the template view.
- Two-Step View. Transform the model data into a logical presentation without any specific formatting, and then convert that logical presentation into the actual formatting required.
- View Flow. Manage navigation from one view to another based on state in the application or environment, and the conditions and limitations required for correct operation of the application.
- View Helper.** Delegate business data-processing responsibilities to helper classes.
- Work Flow. Manage the flow of control in a complex process-oriented application in a predefined manner while allowing dynamic route modification through decision and branching structures that can modify the routing of requests.
There are several different technologies available that you can use to implement a rich client application. The following guidelines will help you to choose an appropriate implementation technology, and provide guidance on the use of appropriate patterns and system functions for configuration and monitoring:
- If you want to build applications with good performance and interactivity, and that have design support in Visual Studio, consider using Windows Forms.
- If you want to build applications that fully support rich media and graphics, consider using WPF.
- If you want to build applications that are downloaded from a Web server and then execute on the client, consider using XBAP.
- If you want to build applications that are predominantly document-based, or are used for reporting, consider designing an OBA.
- If you decide to use Windows Forms and you are designing composite interfaces, consider using the Smart Client Software Factory.
- If you decide to use WPF and you are designing composite interfaces, consider using the Composite Application Guidance for WPF.
- If you decide to use WPF, consider using WPF commands to communicate between your View and your Presenter or ViewModel.
- If you decide to use WPF, consider implementing the Presentation Model pattern by using DataTemplates over user controls to give designers more control.
- If you want to support remote administration of configuration, or if you need to obtain Microsoft Windows® Certification, consider implementing Group Policy overrides in your application.
- If you want to support remote monitoring for your application, consider using technologies such as SNMP and Windows Management Instrumentation (WMI) to expose exceptions and health state.