In-Depth
Component Framework Worth the Struggle
- By John D. Williams
- February 1, 2001
Component frameworks can improve the quality of deployed applications, speed development and reduce development costs—reasons that make considering the use of frameworks too logical to ignore.
Frameworks are not a new concept. One of the first used widely was the Model View Controller (MVC) framework in Smalltalk-80, which provided a structure for building applications with GUI front ends. During the last 20 years, this simple framework has evolved into full-blown application frameworks such as Webridge's Private Exchange for building business-to-business exchanges. Yet many developers remain uninformed about frameworks: what they are, how they work and the value they bring to an organization. It is time to change this situation. Frameworks can speed development, improve the quality of deployed applications and bring tremendous value to a business. What follows is an exploration into the creation and building of frameworks.
Defining frameworks
In their article "Designing reusable classes" (Journal of Object-Oriented Programming, June 1988), Ralph Johnson and Brian Foote define a framework as "a set of classes that embodies an abstract design for solutions to a family of related problems." For example, the MVC framework provided an abstract design, implemented as a set of classes, for building applications with GUI front ends. The design provided a common structure and set of behavior for all applications that used the framework.
I have always liked the definition used by former IBM subsidiary Taligent Inc., which reads, "Frameworks are not simply collections of classes. Rather, frameworks come with rich functionality and strong wired-in interconnections between object classes that provide an infrastructure for the developer." This strong understanding of frameworks embodying predefined behavior through their structure of interconnections and the infrastructure they provide developers is very important—it is what separates frameworks from typical object or component libraries. Frameworks are much more than a random collection of interesting components.
Frameworks have additional characteristics that help them bring value to a business. Like components, they encapsulate data and functionality behind clearly defined interfaces, which adds stability and robustness to a framework's infrastructure. And like components, one does not need to delve into the framework's internals. However, this level of encapsulation can vary from framework to framework. This issue will be examined more fully when the requirements to build an application with a framework are considered.
As the definitions suggest, a framework is not a complete app, but only part of one. Developers must extend a framework to create an application, a process that is tied closely to the way the framework is encapsulated. This extensibility is one of the key benefits of a framework—one that allows it to serve as the infrastructure for multiple applications.
Frameworks are also reusable and can represent significant value to a business through cost avoidance and faster time to market. Frameworks are often composed of numerous reusable assets, including knowledge assets such as the design itself or captured requirements. A framework will also have construction assets, which are the software components that implement it. A typical framework may also have tool assets such as test cases or harnesses that help developers try their applications. As a coherent collection of reusable assets, a framework can be an important investment for an organization.
Frameworks have an additional benefit that sets them apart from component libraries. Typically, when an application uses a component library, the application calls the library as needed. The flow of control remains with the application. In a framework, the flow of control can be inverted, meaning the framework can take control of the flow of a process and choose what parts of an application are called and when, as well as with which methods they are called. This allows a framework to embody a business' process workflow, making a framework an integral, not just an ancillary, part of the business process infrastructure.
What kinds of frameworks are there? Architecturally, they can be found at different levels. At the lowest level, some frameworks support system-level functionality, while others support network access, user interfaces or database access. Microsoft Foundation Classes (MFC) or Java's Abstract Window Tool-kit (AWT) are examples of frameworks at this level; Original Reusable Objects (ORO) is an open-source framework of 'Net components.
Further up the architectural ladder are frameworks that support various types of middleware. Examples can be found for distributed computing, transaction processing and messaging. Sev-eral CORBA ORB systems are actually frameworks for distributed computing, and many tools that support transactions are really frameworks for transaction-based applications. Messaging and other EAI frameworks provide structure for integrating applications.
At the highest level of architecture we find application frameworks, which may be for horizontal or vertical domains. For example, the Webridge Private Exchange is a horizontal framework useful for building business-to-business applications across many vertical domains. The Medical Business Object framework, on the other hand, is designed to support the medical vertical domain. Other vertical frameworks are available for telecommunications, insurance and finance. This type of framework can often bring the greatest benefit to a business because it has a direct bearing on how the organization does business. However, it is also the most difficult type of framework to build.
So how much help can a framework provide in developing an application? Estimates vary from 10% to 95%, and depend on the type of framework used. For example, a GUI framework such as the MVC can provide the structure for a GUI front end to an application, but it will provide no help with the business logic. In this case, one would expect a small amount of help from the framework. On the other hand, an application framework such as the Private Exchange can provide 75% to 95% of the application logic, which is the reason businesses find application frameworks so interesting. Because such frameworks also provide a significant collection of reusable assets, a strong business case exists for adopting them.
Designing frameworks
Building a framework for an organization can be a difficult and expensive undertaking. Some organizations have fired managers who supported this effort, only to have their successors benefit from their foresight. Often, creating the business case for buying a framework is easier than building one. Still, homegrown frameworks can be of great benefit to a business if it can justify the time and financial investment.
The work of creating a framework begins with an analysis of the domain the framework needs to cover. Domain analysis is not the same thing as appli-cation analysis. Domain analysis is the process by which information used in developing systems in a domain is identified, captured and organized with the purpose of making it reusable when creating new systems. Domain analysis focuses on supporting systematic and large-scale reuse by capturing both the commonalities and variabilities of systems within a domain to improve the efficiency of the development and maintenance of those systems. The results of the analysis—collectively referred to as a domain model—are captured for reuse in future development of the framework. Domain analysis is similar to requirements analysis for an entire domain and is not tied to a specific application. Understanding which parts of the framework should be reused and which parts will vary in each application is critical to creating a robust framework.
The next step is the architectural design, the purpose of which is to define the general system rules that govern how the framework will operate. These rules are for general system behavior, and are not for the behavior of the application domain. Examples include defining how the framework will handle concurrency, persistence and distribution. One useful approach to this step is to use established patterns to define the architecture. The use of established patterns can make the system easier to understand and more robust.
The third step is to design the application framework. The use of patterns is also helpful in this step. For example, in their book Domain-Specific Application Frameworks (New York: John Wiley & Sons, 2000), Mohamed Fayad and Ralph Johnson found that patterns can account for 36% of a framework's design. The actual concept of patterns and pattern languages began with Christopher Alexander in his books A Pattern Language (New York: Oxford University Press, 1977) and The Timeless Way of Building (New York: Oxford University Press, 1979). Alexander applied his exploration of patterns to building architecture. Others then took these concepts and applied them to software development.
Beginning with the 1995 book Design Patterns: Elements of Reusable Object-Oriented Software by Erich Gamma et al. (Reading, Mass.: Addison-Wesley), there developed a whole body of literature on software patterns and anti-patterns. Patterns, it was discovered, can be an important part of the framework's design. The structure of the framework needs to be determined in this step. Will it be a monolithic structure or a larger one made from a set of smaller integrated frameworks? The former Taligent began by creating monolithic frameworks, but moved to frameworks that were a cohesive collection of many smaller entities. Its CommonPoint framework was built from more than 100 smaller constituents.
The fourth step is to implement the framework, which can be done in a wide variety of languages. If an object-oriented language is used, both abstract and concrete classes need to be created. The choice of language will affect how the framework is used and expanded. For example, some early frameworks were expanded by subclassing abstract classes using an inheritance mechanism. Another approach is to focus on components and their interfaces; this allows for implementation in a wider variety of languages, but it also affects how developers use the system.
Once the implementation is complete, the framework can be tested for functionality and usability. Testing for functionality, while complex in a framework, is a fairly straightforward effort that is necessary for any software. Usability testing, on the other hand, is more problematic. How does a developer know how usable the framework is? This is not a question of domain fit, but a question of the ease with which developers can implement applications using the framework. For example, will the framework be simple, but restrictive to use? Will the framework be parameterized to make it customizable? The latter will make it more complex to use, but developing frameworks always requires this type of tradeoff. The user needs to be understood. How technically sophisticated must the user be to utilize the framework effectively? Also, test cases must be created for developers. Often, when there are problems with an application, developers will want to blame the framework first. Providing an adequate number of test cases helps developers find the source of problems more quickly.
Documentation is one of the most overlooked but important aspects of framework development. How can developers use the framework if there is not enough documentation to help them understand it? One of the advantages in using patterns as part of the design process is that they can be used for documentation as well. A pattern language may also be used to describe the framework.
Yet even with all of this work, there is still more to do. Most frameworks go through three or four iterations before they are ready for use. Using patterns and learning from other frameworks is one way to reduce the number of iterations. However, significant time will be spent refactoring the components and hierarchies in the framework. A behavior-preserving approach may therefore be needed to minimize maintenance issues.
Building with frameworks
While building a framework is a challenge, building with a framework presents its own set of obstacles. Will an application be built using a single framework or will a system of frameworks be constructed? Are integrated or unrelated frameworks needed to build the application? Answers to these questions will help define the skill sets needed and the issues to be faced in using frameworks.
Frameworks offer developers different ways to expand and use them. Many of the early frameworks were white box, in which the source code is available to the application developer. The code was provided not just to give the developer a warm, fuzzy feeling; white-box frameworks are typically expanded by subclassing existing abstract classes, which requires the developer to understand the internal workings of the abstract parent classes. The best way to understand the internal workings of a class is to look at its source code.
Other frameworks are constructed as black boxes, which are customized through their parameterized interfaces. Black-box frameworks are more like components because they can be accessed only through their interfaces and no insight is available into how they work internally. Some developers view the issue of white-box frameworks vs. black-box frameworks as a choice of good vs. bad. It is not. It represents a range of choices in how developers interact with a framework. White-box frameworks are easier to customize, and thus represent a reasonable choice for relatively new frameworks that have not yet stabilized completely. Black-box frameworks need more stability because all usages in the available interfaces must be anticipated.
Most frameworks are expanded in one of two ways. The first is to create "hot spots" in the framework where variability is allowed. Returning to the discussion of domain analysis, the parts of the framework that remain unchanged across applications can be frozen. Areas expected to vary from application to application can be set up as hot spots where developers can plug in their own specific code. Hot spots are usually created as abstract classes or templates. The creator of the framework will define the interfaces of the hot spot and the set of generalized responsibilities it must fulfill. The application developer must then plug in an application-specific replacement. Often, framework developers will provide a number of concrete classes that can be used or that can serve as examples for customizing hot spots.
The second technique used to expand frameworks is hooks. These are often virtual methods in classes that application developers are expected to override with their own application-specific behavior. Abstract classes can also be used as hooks. Both of these expansion techniques can be combined as the framework developer sees fit.
Integrating non-related frameworks presents another set of challenges. There may be a gap in the functionality of frameworks the developer needs to fill with custom "glue code." At other times, frameworks can overlap and code to manage that overlap must be created to ensure that each framework is updated appropriately. Problems may also arise when integrating legacy frameworks. Developers often need to create adaptors that integrate both legacy and new components.
Finally, we return to our earlier discussion of inversion of control. Inversion of control means that the framework rather than the application is in control of the flow of processing. This reversal can present a challenge when integrating unrelated frameworks. Which framework will be in control? The question is easier to deal with if the source code for both frameworks is readily available; this way, it may be possible to integrate the control loops. Otherwise, synchronization code may have to be written for the frameworks.
Framework success
Clearly, there are a number of challenges to building and using frameworks, yet the benefits of adopting domain-specific frameworks can be great. Frameworks can speed development, dramatically reduce development costs and significantly improve the quality of deployed applications. Successful adoption of a framework will take time and the most-skilled people in the organization. Time is also needed to learn how to use a framework, and skilled people are again needed to integrate a framework with the rest of the application environment.
However, by moving forward with some basic knowledge of frameworks and how they function, the chances of success are increased along with the potential benefits to an organization.