Introduction to Developing Object-Oriented Frameworks
For someone familiar with object-oriented development, developing an object-oriented framework will be both familiar and new. It will be familiar because framework development stresses the lessons of good object-oriented development and new because it brings new challenges and surprises. One of the biggest challenges is accepting that an object-oriented framework involves delivering more than the executable code and limited documentation you've developed before.
1.1 What Is a Framework?
In Design Patterns, Gamma et al. provide the following definition of a framework: "A framework is a set of cooperating classes that make up a reusable design for a specific class of software" [Gamma 94, p. 26]. Extending this definition just a bit, we say that a framework is a set of components working together so they address a number of problems in one or more domains. These definitions are essentially the same. These definitions share key aspects.
A framework involves a number of abstractionsclasses or components.
These abstractions cooperate or work together to do something. A framework takes a team of individual abstractions and defines how they work together. This definition is the reusable core (design and implementation) of the solution.
The abstractions and how they do what they do are reusable. A framework isn't a class library. A class library's purpose is to provide a set of classes and functions that are common almost to the point of being ubiquitous. A framework provides reuse at the next level up for processes and functions that are "almost" common. In fact, a framework can be built on top of a class library, providing this next level on top of it. Although a framework should rely heavily on design patterns, a framework isn't just a group of patterns. It is the combination of designs and implementations, targeted to meet a set of needs in a general way (see our next point), and built on a core architecture that can be extended (customized) to fit the needs of different uses. The places where this extension is supported are called extension points (also called hotspots).
The framework addresses a specific area. A framework must have a target area it addresses (a domain). What if it doesn't? What if you created the ultimate framework that could be used to build anything? Actually, it's too latenot only have you been beaten to the punch but there are lots to choose from, all called programming languages. A programming language provides a set of abstractions (primitives) that cooperate (operations) and are all reusable to write any program you want. OK, it was a trick question, but it makes an important point. A framework can't be everything to everybody. It must address a specific set of objectives. This book helps you explore how to pick the objectives and understand what that means to the framework development process. We can't pick the objectives for you, but we can give you some patterns to help you decide what objectives are right for you and help you to focus on those objectives.
Before considering something to be a framework, it should meet each of these criteria in some way. It isn't good enough to simply say the framework addresses the domain of constructing celestial bodies (planets and so on), to pick an absurd example. We have to be able to do it! We have to provide the framework in such a way that it consists of abstractions that work together and can be reused (extended) to address the domain (celestial bodies in this case). Can we write a framework that addresses the complete planet domain? Probably not, and even if we could, we probably don't want to pay to do it. On the other hand, we should know which celestial bodies we want to create and can thus scope down the domain to a subset of all possible bodies. For example, we could choose to create only simple nongaseous planets. It's a tradeoff, though: we are deciding that when we have to create a gaseous planet or a planet with rings or moons, we won't get the benefit of the framework. However, the good side is that this focus reduces the complexity of the framework. Now the framework can be more focused and can omit the support for customization (extension) needed to create planets that have rings or moons. This example, although absurd, points out the importance of excluding outlying conditions, a topic explored in more detail in the Tor's Second Cousin pattern (see Section 4.2).