Jo Grant and Craig Wolpert are members of the IBM Workplace and Lotus Software ISV Technical Enablement team. This article is the result of information gathered while developing a Composite Application sample for Notes 8. It is one is a series on developing composite application. We will post more articles to this forum as they are completed. Please provide feedback on the content and how it is presented by Monday (2 April 2007).
Designing Composite Applications: Component Design
Jo Grant, Dan Kehn, Craig Wolpert
This article mentions a sample which is currently under development.
This article mentions screenshots and a sample currently under development. This document will be updated with screenshots at a later time.
Review Composite Applications information distributed with Domino Designer 8 Help
Review the Composite Applications Tutorial and Documentation - "Building Composite Applications for IBM Notes 8"
Composite applications are a key element in a service-oriented architecture (SOA) and contextual collaboration strategy. They support business flexibility for companies and organizations who wish to rapidly respond to changing demands in today's competitive markets. Composite applications are aggregations of user interface components that are loosely coupled to support inter-component communication. Components can be reused in multiple composite applications. The ability to combine multiple implementation technologies into a single application provides significant business value. It enables companies to protect and extend their existing assets with increasing degrees of flexibility, and to respond quickly and cost effectively to their emerging business requirements, with applications that are significantly easier to create than multiple application development environments.
The composition application model is already familiar to IBM(R) WebSphere(R) Portal developers. This approach has been extended to Notes version 8, enabling Notes developers to surface their Notes applications as one or more components in a composite application. IBM(R) Lotus(R) Domino Designer(R) has been extended to leverage the property broker, as well as to provide a more intuitive user environment. Notes version 8 also supports the inclusion of Eclipse components and a composite application may have any combination of Notes components and Eclipse components. These may be just be presented together in the same UI for on the glass integration or, if extended to use the Property Broker, will fully be able to interoperate with each other. You can define composite applications using the Composite Application Editor or the WebSphere Portal Application Template Editor.
The development of Components for Composite Applications is rather different from traditional Eclipse or Notes application development. It is highly desired to create components that are sufficiently flexible that they can be simply deployed in applications at later dates without significant rework. This article discusses approaches that can be made in designing such components and best practices to consider adopting along the way. This does not present an exhaustive list of everything possible with the features given.
Although Composite Application Components are frequently built upon existing assets, they nonetheless have a very open definition. The ability to do almost anything you like is very powerful, but can also lead to uncertainty of what you should do and how to establish a standard approach to development. It should be understood that the categorization of elements given in this article are suggestions of one possible approach. No approach is wrong. It either works for your company's use case, or does not. If you think our suggestions will work for you, then adopt them. But feel free to change them if you have other requirements.
It Takes a Village
Creating a composite application does not automatically bring about the benefits of good integration. It is quite possible to create components that operate no better together than two separate web pages side by side! Creating the correct development processes in your organization for coordinating these efforts will ensure that you can capitalize on the benefits of composite application design. One benefit of composite applications is the ability for loosely coupled components to exchange information. A benefit of loosely coupled components is the ability to reuse in multiple composite applications. A shared type definition repository, common naming convention for property and action names, central registry and documentation of available components are examples of process which improve the development of components and the assembly of composite applications.
A loosely coupled Composite Application Architecture also enables diverse groups in different locations to leverage each others efforts and to interoperate with each other. For example, one department may be working on the accounting application for a company while another group is working on a Sales Lead Tracking Application. The Composite Application vision is that it would be possible to add into the accounting application some components from the tracking application to give pertinent views of sales leads in an accounting context. Similarly the tracking application could incorporate components from the accounting application to give accounting information within a sales lead context, thereby enabling end users to conveniently see related data within the context of their own domain data. As your company develops more and more composite applications, the potential for integration increases exponentially. The goal is that the whole is greater than the sum of the parts.
If your company already has something akin to an Architecture Review Board, that might be an appropriate place. If your company is smaller, even nominating a single person to be responsible for maintaining the approved list of the shared types will serve this need. Such an organization must not slow down development. Too much focus on process will cancel out the benefits you might otherwise gain. Instead it is more of a brainstorming center, where different groups can keep other groups informed of their ideas and all can realize the potential for benefit across all the groups. These and other topics are discussed in more detail in the article Designing Composite Applications: Managing the Process.
Types of Components
There are very few technical restrictions on what can comprise a component. It is, literally, a rectangle of UI that has some well defined entry and exit points. However there are a few general categories that we can define that help us look at different approaches to their categorization.
The ability of composite applications to share components between applications blurs the distinction between the original applications. And this is the perfect user experience. A user should be able to move between the activities they need to do without any actual awareness that they are moving from one domain to another. However at the component development level components will tend to come from and be related to a single application domain. They will have interaction points that allow connections to other domains, but in the most flexible design these are established at application assembly time and not component design. On the purely practical side of development, effort is usually divided along these application domains. Resources, timetables, and deliverables are usually accounted for in divisions and so it is practical to look at the design along those lines.
The included Sales Lead example is comprised of three basic application domains.
- There is the core sales lead application, which tracks companies and sales leads.
- There is a discussion applications, which contains discussions about sales leads.
- And there is a legal application, which tracks contracts issued to customers and their revisions.
Domain Centric Components. These components are the center of attention of the created applications. When creating a composite application to cover the functionality of your domain it is likely that major UI elements will be focused solely on your domain and only make sense within the context of your domain. This is often the first tier of component development. If you are converting an existing application then one approach is to first ensure parallel functionality in your composite application. These large blocks bring the most amount of functionality in the quickest. They might be used a few times within your application, but are less likely to be used by another composite application. Consequently, these may be more tightly coupled for additional richness.
In the provided sample application components such as CompanyList, SalesLeadList, SalesLeadDetail, and SalesLeadEdit would be examples of Domain Centric Components. These components are primarily the center of attention on each page in a composite application. In most cases each page only has one Domain Centric component which is the center of attention. The other components on that page will provide the peripheral vision into one or more domains and be called Contextual Domain Components or Generic/Utility Components. As the names describe, a Domain Centric Component is the center of attention and will occupy a large area in the center of the page. The components which define the peripheral vision will be smaller, normally positioned at the edges and provide filtered views into a domain. Minimizing real estate usage is a primary way that contextual components differ from centric components.
This pattern of component development and others are discussed in the article Designing Composite Applications: Composite Application Design Patterns.
Contextual Domain Components. If Domain Centric Components are the center of attention of an application domain, then Contextual Domain Components provide the peripheral vision. These are the components that decorate the peripheral view in your application and provide domain related information, but in a context specific way or belonging to a particular information subset. In a classic conversion approach, this would be your second tier of development. They are not essential to the fundamental workings of your application, but they increase usability through showing contextual information and saving on page transitions or cut and pastes. As such they are likely candidates for inclusion in other composite applications. In the same way they can provide domain related information when there is a element in both application domains that is common.
If you look for scenarios which involve transitions form other domains to yours, these may indicate an opportunity for a Contextual Domain Component. This will increase user productivity and satisfaction by providing support to the center of attention component in their domain rather than requiring the user to launch a separate interaction thread to access your domain information.
Alternatively, another approach to converting an application to a composite is to first produce some contextual information components in a way suitable for dropping into other composite application. This might be an easier initial approach that allows real value to be quickly achieved as developers become familiar with the Composite Application programming model. This also demonstrates the value of reuse early in your adoption of the composite application architecture. If the application is large and complex a longer schedule may be appropriate for total conversion. Or if the application is done with quite a different architecture (e.g. a green screen application running on text terminals served by a back end system) then total conversion does not make sense. But much like web services provide access into these back end systems, Contextual Domain Components can be developed to bring information out of these systems (quite possibly using those same web services!) for reuse in new composite application projects.
In the provided sample application components such as CompanySummary, LeadSummary, and LeadList ConstrainedByCompany would be examples of Contextual Domain Components. You can see how they are deployed within the Discussion and Legal application domains to bring in related Core information within their contexts. The Company and Lead components were not only designed to be used in our sample application but could easily be used in other composite applications which require a filtered view into Company or Lead context. Notes 8 comes with many contextual domain components that provide access to mail, calendar, contacts, todo and feed domains.
Generic/Utility Components. In the course of developing a composite application there are elements you will come across that are not specifically tied to any application domain. These are useful components that have applications for anyone developing composite applications. In the provided sample application components such as Pager and Browser are examples of this. These provide programmatic and user initiated page navigation and web page browsing. Both are features that are not specific to the Sales Lead application and are quite applicable elsewhere.
Now that we have a framework for classifying types of components we can discuss the sorts of process that a central group might organize around composite application development.
The most important technical aspect is maintaining a common set of data types. Components communicate with one another in terms of data sent as properties to actions along a wire. These wires cannot be made unless both end points use the same data type. Two components may have the concept of a date, but unless these are identically defined (both namespace and type) they cannot be connected. So a review group (or even a single person) can maintain a list of common data type definitions across the company. As each group documents their component functionality, they should also identify the different data types they require for their properties and actions. Ones that match up with existing company definitions can be determined and the common definitions used. For the new and unique ones, they can be added to the list of company definitions. Another approach is to choose a generic type (such as xsd:string) where you want to keep the standards loosely defined. This can result in a loss of exactness on the type matching in the wiring tool, but can make for greater reuse with components from different namespaces. Both techniques are valid and you should strike a balance between them appropriate for your company.
In many cases, Domain Centric Components only talk to other Domain Centric Components and many of the data types defined on them may not be of general interest. But Contextual Domain Components will, ideally, have interest from a wide variety of consumers. For these it is essential that there is coordination for data types. Also, data type coordination will be required where Domain Centric Components communicate with Contextual Domain Components from other domains.
Maintaining a list of common data type definitions across a company or organization is the first step in allowing you to develop components which can be reused in composite applications. See the article Designing Composite Applications: Managing the Process for details approaches you can take to this and other central activities to optimize the use and development of Composite Applications in your company.
There are several types of repeated patterns that occur when developing components for use in composite applications. These are handy short-hand options to consider when designing the components that you need for a composite applications. Similarly there are layout patterns which are useful ways to arrange collections of components and application patterns that can give structure to your entire application.
These are covered in detail in another article in this series: "Designing Component Applications: Design Patterns".
Deciding Component Granularity
Different approaches can be taken when deciding exactly what makes sense to deploy as a component. If you are designing things from scratch, as with a new application, it can be useful to pick one of the component patterns referenced above. With this as a basis you can see what portions of your application domain fit those patterns.
Technology choice is another important decision. Notes 8 is based on Eclipse's rich client platform and Expeditor, which means that components can be based on either Notes or Eclipse architecture. Eclipse offers many rich interaction and reuse capabilities, but requires Eclipse development skills. Similarly Notes has many benefits in the client and server space that require Notes development experience to use. To benefit the most from a Composite Application Architecture consider using a technology that best serves the features you are trying to implement tempered by the existing skill sets in your organization.
Another useful method for new applications is to work backwards. Generate what you want the application to look like, then work out what components you would need to build that. If you start from the screens depicting the application, in a story board for example, you can first identify areas in common. Any piece of UI that appears the same (or similarly) on several application pages is a candidate for making into a component. The next step is to go through your story board and look for sections of UI that either belong to other application domains, or that might make sense being used in other application domains. Through this method of successive division you can turn your design into components.
Designing components to port an existing application is both harder and easier. It is helpful that you already have an application design. But it is harder in that you have to compromise between using what you already have and designing for component reuse. In the case of a Notes application, you have some fundamental types of UI to work with (e.g. views, forms, pages, navigators, framesets). The companion article "Designing Component Applications: Notes Components" details a worked example of converting a Discussion Database to a composite application. The principles outlined there are applicable in general to many types of Notes applications.
For Eclipse based applications, you have the advantage that it is already based on Views which translate directly to Components. When designing for an Eclipse rich client application, the views and perspectives are defined at design time. In Notes 8 these activities are decoupled. Components are designed in advance, and later assembled; possibly in many different applications. That means that the level of granularity chosen for the views of an existing Eclipse application may not be the best choices for components in a composite application. Many views will directly map into components however some views may present subsets of UI which you might want to have available as components. You can apply the method of successive divisions above to break down appropriate views into components. The companion article "Designing Component Applications: Expeditor Components" and "Developing Composite Applications: Leveraging Existing Java Applications" will provide more information on Eclipse based applications.
Communicating Between Components
Components communicate with one another through the use of properties and actions. However there are several different ways you can use these to conduct operations.
Properties broadcast outgoing values. These can be communicated through a wire and consumed by an action. The most simple method of use is for propagating a simple data value. For example, if a component presents a list of data items, it might broadcast a property representing the Name of the currently selected item. But we have a number of choices when we publish such values. Data items can have a number of entries. For example Name, Part Number, Supplier Code, Quantity in Stock, etc. The present implementation of the Notes property broker only allows you to broadcast items that can be expressed as strings and does not allow the option of broadcasting a complex item as-is. For maximum re-use of components you should consider adopting a lowest-common-denominator approach and publish each entry separately. This can be limiting, and you will have to balance that against reuse.
One approach to get around this, though, is by defining a method for serializing multiple attributes into a single string. This is the approach taken in the mail component where a single string using the mailto: format is passed. This is an encoded standard that can include a list of recipients, courtesy copy recipients, blind courtesy copy recipients, a subject and body of text. Another method often used for Web Services is for the details to be represented with an XML data structure. Some drawbacks should be noted. Firstly any time any element changes, the entire structure would have to be broadcasted. So this is mostly only appropriate for groupings of settings that have a relationship on the backend. Secondly, there is a reduced chance that this component will be able to interoperate with components from other domains unless the method is an industry or corporate standard. Although individual entries may have types in common, the overall data structure is specific to the application domain. This moves the design away from being loosely coupled.
Another method of using properties is for event notification. They are only broadcast when something changes. For example a component performing a complex operation might broadcast its state. While it is submitting it might broadcast a value in a state property to indicate this. Other components might be structured so that they can listen to this state and disable themselves when the component it is linked to is in an inappropriate state.
For greater reuse, individual components should avoid dictating the application flow. Instead they can defer that decision to assembly time by signalling their view state change. A common component for handling transitions between components can then coordinate the change (and again this decision is deferred until assembly time, not design time, increasing the reusability of the component). For example, in the included Sales Lead Application, many components broadcast a property called "ViewState". This contains a pre-defined value of what sort of operation or state transition the component would like to propagate up to the application level. For example the "Company Edit" component sets this to "#company.saved" after a save function has been done or "#company.closed" when the close button has been pressed. At application assembly time these are wired to a page switching component that maps these notifications to the specific page transitions desired.
Actions consume the value of a property. These values come from wires which are connected to properties. Like properties, these can be used in several different ways. As with properties, the simplest way is for a simple data receiver. The component may consume this property and just store it, pending a later operation, or it may do a single data orientated operation, such as updating the value of an edit field. For these actions the data types directly correspond to the field they represent.
Another typical use is to consume an action that has a direct result on the display. Most commonly, this takes the form of passing to an information retrieving component a filter whereby it finds the corresponding data record and displays the contents or a subset of the contents (e.g. a view filtered by a category). Resultant values may be further propagated via properties. The data type of this is typically a unique ID or some other index. For a listing component this may be some sort of search criteria which usually takes on the data type of the corresponding field. For a more general search string, you could define a special type, but for maximum interoperability you might also consider making it just the generic xsd:string type.
In other uses it may control the display mode of a component and limit what UI gestures are available. Maybe in some cases a component will allow search by displaying a search button and in other cases the search button will be disabled or hidden.
The above case deals with service type operations for actions, but only in the case where they accept a single argument. What if you have a service you want to expose through the component that requires several inputs? The present implementation of the Notes property broker only allows an action to receive a single argument. As above, you have to decide between re-use and richness if you choose the lowest common denominator. One approach is to use serialized types as discussed above, with the same limitations. Another approach to deal with actions that desire multiple parameters is to have a data receiver action correspond to each possible argument. Lastly you have a "doit" type gesture in the UI. For example a button, hot spot or right menu click. When this is triggered it takes the values that have been previous set, and if all non-optional ones are set, then it enacts the operation. (If insufficient values have been set, the UI can show state to indicate this. For example a button could be disabled.) This has the advantage of being based on simple types, and is useful in a variety of circumstances where you many not have all data available in the context, or coming from several components and it leaves the user in control of the consistency of the information before some real state change is made in the system of record.
This article has chartered some basic approaches for designing components for Composite Application development for maximum reuse. There are many different strategies you can use to address the challenges of providing the best possible palette of components for your application developers. But with the overview presented in this article, you can select an approach that best suits your company. In doing so, your development organization will be able to respond more quickly and cost effectively to emerging business requirements. In addition, your users will benefit from a richer applications that combine interoperable components from multiple domains into a single environment.
Feedback number CWOT6ZFLAW created by on 12/11/2019