Development of Object-Oriented Frameworks
Todd Hansen—Northern Telecom, USA
Craig Hilsenrath—Greenwich Capital Markets, USA
Bill Opdyke—Lucent Technology, USA
Steven Fraser —Northern Telecom, USA
Honna Segel —Northern Telecom, Canada
Erich Gamma— IFA Consulting, Switzerland
The purpose of this workshop was to give attendees
a better understanding of how to avoid pitfalls and develop successful frameworks. We posed three questions:
• How can we achieve the right level of generality in a framework given shifting requirements?
• How can we communicate the framework architecture and achieve usability?
• How can we design effective economic models to clarify what should be framework-developed?
The format of the workshop included an initial
group introduction session. The goals of this session were to briefly introduce each participant and discuss their expectations, experiences, views on successful framework characteristics, and areas of interest. Subsequently, participants were divided into discussion groups based on their interests. Each group brainstormed on one of the three topics and presented their findings to the entire audience. The workshop concluded with a group discussion of potential framework topics and a list of possible next steps.
1 Workshop Specific Content
Most participants were expecting to gain insight
into framework development issues such as training, usability, and economic justifications. Others
wanted to learn from the successes and failures
of experienced framework developers. A few just anticipated good soul-refreshing conversation.
1.2 Areas of Interest
Participants expressed personal interest in the
• refactoring designs
• testing frameworks
• patterns and pattern languages
• effects of centralization and decentralization on framework development and adoption
• how to turn a framework into a stand-alone product, and how to support it
• how to deal with feedback between framework developers and user groups
• relationships between frameworks and design patterns/architectures
• experience with reuse of frameworks
• adaptability of frameworks
• how to represent a framework
• how to capture the correct interface
• requirements collection
1.3 What Is A Framework?
There was no clear consensus on a single definition for a framework. However, several definitions were suggested:
• an abstraction of, or schematic for, a family of problems
• a group of objects which meet a well-developed set of functional requirements. The framework may incorporate other frameworks and objects
• a set of interacting components designed to facilitate application development for a specific domain
• a reusable design expressed in text, graphics, and code, which captures design decisions
• a collection of classes and their relationships, used to capture the reuse of design and possibly of implementation
• structure, relationships, and roles for composing objects to implement a software application for some domain
One distinquishing characteristic of frameworks is that they impose a collaborative model to which applications must adapt. This implies that there is an inversion of flow control so that the thread of control now lies within the framework, not the application.
A framework is not an API or a subsystem.
1.4 Characteristics of Successful
Successful frameworks are cost-effective and strategic. They are usually built by a small number of highly-integrated, experienced OO designers (i.e., fewer than four designers) and delivered quickly (i.e., something usable within one year). Framework introduction is managed by the design team. To minimize excessive code churn, customers don’t exploit the framework before it is reasonably mature.
Frameworks are used by choice, not by organizational or corporate mandate. Equal treatment within the organization is accorded application designers and framework developers, and framework changes are communicated via a controlled feedback mechanism running between application teams and framework designers.
Framework-savvy organizations recognize the importance of framework development even though this activity is not a direct source of revenue. Strategic frameworks survive cost-cutting measures.
Successful frameworks address relevant problems and are scoped to a single domain. The framework does not try to do too much. This scoping is based
on extensive domain analysis, not preconceived solutions. Good designs are decoupled (e.g., DB and UI) and make modest—not excessive—use of inheritance and aggregation.
Successful frameworks meet customer performance, functional, and productivity requirements. They are not too general, too complex, or too flexible. Rather, they are well-documented, easy to understand, use, and extend. Upon delivery, they are both testable and tested.
Successful frameworks are distinguished by repeated reuse, typically by more than three applications. They are easily adapted to changing requirements. Although a good framework supports application delivery, it is supported and maintained as a separate product.
1.4.3 Examples of Successful Frameworks
1.4.4 Examples of Unsuccessful Frameworks
• Cosnos—too little return on investment
• NextStep—business mismatch (end user
• Motif—hard to use and to extend
• CommonPoint—too big an effort
2 General Discussion and Conclusions
2.1 Breakout Group 1: Achieving the Right Level of Generality in a Framework Given Shifting Requirements
This discussion group addressed different development strategies that can be used to minimize requirements churn in frameworks that cater to multiple dependent customers and applications. Four basic approaches were considered: Depth First, Breadth First, Reference Model, and Pearl Dive. The group defined each approach and recorded the potential benefits and drawbacks.
2.1.1 Depth First
Gather requirements from all customers but select one application around which to develop the initial framework. Add new behavior to the framework by considering each additional application individually.
Requirements are scoped primarily around one specific application. A framework can then be produced quickly, allowing customers to provide early feedback to the framework team, and allowing low-level design issues to be identified and resolved early in development.
Framework designers can expect significant design and code churn as new requirements are added. In many cases, it may be difficult to rework the framework to support additional requirements. Framework robustness may be compromised.
2.1.2 Breadth First
Gather requirements from all customers and consider all these requirements when developing the framework. Try to generalize the framework enough from the beginning to support all of the applications.
All known requirements are considered from the beginning of the development effort so that framework design and code churn are reduced.
Numerous initial requirements can be overwhelming and may lead to long development delays before anything useful is delivered to the customers. A lack of early understanding of low-level requirements, and generally slower iterations, constitute potential risks to the design.
2.1.3 Reference Model
Build a generic reference application representative of all customer requirements. This application can be used to train users and to provide a model for adding new behavior to support new applications. This is
a specialized version of both the Depth First and Breadth First approaches.
The reference model is generally simpler and can be useful in training customers who will use the framework. It can be produced quickly so that customers can verify their requirements early. Customers gain confidence in the framework by working with the reference application, and they can test the feasibility of adding new requirements to the framework.
It may be difficult to build a reference framework which is representative of all customer requirements. It will also take additional time to develop the reference application, and some of this framework behavior may be non-reusable.
2.1.4 Pearl Dive
Pearl Diving is a combination of the Depth First and Breadth First approaches. Consider requirements from all customers and stratify them based on common behavior or characteristics. Select one reference application from each group and use these requirements for initial framework development.
This approach limits the scope of the requirements while still considering the basic behavior required
by all applications. The framework can be produced quickly and customers can provide early feedback
to the framework teams. Low-level design issues are identified and resolved early. Pearl Diving can help identify cases in which a need for multiple frameworks is indicated by the resulting stratification.
Some requirements could be missed if stratification is performed improperly. This approach is beneficial only when the number of framework customers is significant.
The group did not reach a consensus as to the best approach in all cases. However, it seemed clear that
a combination of both Breath First and Depth First approaches was desirable. This combination provides two key benefits:
• It reduces framework churn introduced by new requirements.
• It quickly provides framework behavior that customers can use and verify.
2.2 Breakout Group 2: Communicate the Framework Architecture and Achieve Usability
This discussion group focused upon how to communicate the framework intent and achieve usability. Group members identified five phases in framework adoption and usage, and the solutions differed with each phase.
2.2.1 Phase 1: Convincing Potential Users
During this phase, it is important to demonstrate architecture in practice. Overcoming "not invented here" attitudes can be a challenge. The group noted several forms of communication that can help convince potential users:
• examples — Begin with working examples and extend them in real time.
• testimony — This would preferably come from other users of the framework. Present the strengths and weaknesses of the framework.
User testimony will enhance credibility
and help avoid over-expectations.
• A test suite constraints document.
• An architectural overview.
2.2.2 Phase 2: Getting Started
Whereas the prior phase focused upon how the framework worked, this phase shifts attention to
communicating how people should work with the framework. It is important to teach rituals that can solve simple problems simply.
Several forms of communication are important here:
• a cookbook of usage patterns, rituals, practices
• a concepts manual (to present the "big picture")
• a simple interface design; visualization tools
2.2.3 Phase 3: Development
This phase begins several days, weeks, or months after developers have begun using the framework. This phase seeks to initiate the developers into some of the "mysteries" and techniques for applying and extending the framework to handle more complex applications.
Key forms of communication in this phase are:
• sharing of principles and values, perhaps at a user’s conference
• more of when and why to apply the framework
• a reference manual
• consulting (in "short bits")
• a "help system," with a second, more detailed level of information
• CRC documentation
2.2.4 Phase 4: Outer Limits
In this phase, developers attempt to extend the
framework in ways that stretch the limits of the framework’s capabilities.
Forms of communication that are important here include:
• intense consulting
• techniques for disciplined development
• a more comprehensive test suite
• a description of framework subtleties (algorithmic, complexity)
2.2.5 Phase 5: Usability
This phase focuses most intensely on the internal structure of the framework (rather than how the framework is used). The usability phase catalogs techniques, not only for solving nearer-term problems, but also for restructuring the framework so
that it is easier to evolve and extend.
It is important to document both the incoming
and outgoing messages related to a class. Naming techniques (name spaces, metaphors) should be described, as should techniques for isolating parts
of the framework that change most frequently. You can then reorganize the framework so that a new
user might quickly grasp a naive domain model,
then motivate the deltas from the naive model.
Apply aggregation where it can clarify the design.
In summary, this group described five phases in framework adoption and usage. Several forms of communication seem to recur among those phases: working examples, consulting/ support, and documentation targeted to various levels of detail. As a user community matures in its understanding and usage of a framework, the communications become more detailed and the topics more advanced. Staff members who are responsible for framework development and adoption should regularly assess which phase their customers are in and carefully focus their
communications to meet user needs.
2.3 Breakout Group 3: Design Effective Economic Models
to Clarify what Should Be Framework-developed
This discussion group concentrated on the framework lifecycle and the issues associated with each phase of this lifecycle.
Create from Scratch
This phase applies for the first applications that are developed on a framework. Since the framework has not yet been written, it must in fact be developed simultaneously with these initial applications.
The initial customers must be friendly and the framework team must be "easygoing and flexible."
The perceived value of the framework must exceed the perceived cost (adoption or replication). This often requires cooperative, integrated development
of the framework and the first several applications.
Generally, the applications chosen need to be delivered as quickly as possible. The "customer" may demand that your framework be early (before it’s done), stable (before it’s been iterated through), and low-risk (before it’s been verified). Should the project fail (and most do under the above circumstances), any supporting framework will take some of the blame—even if it did not cause the failure.
Re-engineer Some Existing Applications
Here, the applications pre-date the framework. Designers must discover the framework "hidden within" the set of applications and then re-engineer the applications around the "extracted" framework.
Since the applications already exist, time-to-market pressures are reduced. However, the effort to extract the framework can interfere with ongoing feature roll-out.
Your framework exists in at least one stable version, and a couple of applications are successfully using it. Since the framework is relatively stable, learning the framework makes sense and cannot be considered a waste of time.
Customers who underestimate development costs will low-ball these costs versus reusing the already-existing framework. (They will tend not to buy the framework.) Customers who understand development costs tend to desire non-programming solutions. (They won’t buy the framework either.) Framework groups need to find organizations
that are between these two stages.
Those customers who choose to use a framework may find themselves in a conflict of interest: use
of the framework brings increased productivity
and may result in "downsizing."
New sales produce income with little or no incremental costs. Rouge Wave and IMSL are good
examples. Both of them are supported as commercial products.
Most frameworks never reach the Volume/Cash-cow phase. This may be due to selective sampling (most people never hear about successful, internal-only frameworks) or it may be due to the relative lack of success of internal frameworks.
2.3.4 Standardization Phase
Framework functionality is a commodity. For example, Rouge Wave’s original container class library was "standardized" by the STL.
A framework in the standardization phase can serve as an effective launchpad for new products which can bring in new profits. Developers can quickly build added-value products on top of the framework. For example, Rouge Wave’s network containers are built on their original container classes.
The framework is essentially frozen. Fixing known bugs may be impossible, so they become "documented known bugs."
Some frameworks are so close to an application that this stage is never achieved (e.g., OTS - Object Transaction Service from OMG).
3 Next Steps
Workshop participants expressed interest in further exploring the question— what is a framework? This discussion has been taken on-line by the group. Other interesting topics were proposed but not considered owing to time constraints. Specifically,
• framework integration and interoperability
• testing frameworks
• manage teams with frameworks
• documenting via patterns
These are all potential candidates for an OOPSLA 97 framework workshop.
John Artim email@example.com
Kent Beck 70761.1216@CompuServe.com
Terry Cherry firstname.lastname@example.org
Rich Demers email@example.com
Steven Fraser firstname.lastname@example.org
John Gilbert email@example.com
Todd Hansen firstname.lastname@example.org
Steve Hayes email@example.com
Craig Hilsenrath firstname.lastname@example.org
Wouter Joosen email@example.com
Peter Kriens firstname.lastname@example.org
Mark Linton email@example.com
Jeff Oakes ustvyzab.ibmmail.com
Bill Opdyke firstname.lastname@example.org
Arthur Reil email@example.com
Jon Siegel firstname.lastname@example.org
Bedir Tekinerdogan email@example.com
Larry Williams larryw@ObjecTime.com
Joe Yoder firstname.lastname@example.org