Created 9/19/99 - Last Updated 9/24/99 - Jack Harich - Go Back
These all revolve around discovering the essence of good frameworks.
Our
purpose is to help developers learn how to build better frameworks. How
can we systematically do that? By capturing the essence of what makes good frameworks
in a way that makes that knowledge easily applyable when evaluating, creating
or improving frameworks. The result should be that any developer who is truly
committed to improving their skills can study all this, apply it, and make better
framework decisions immediately. We hope to use this material ourselves immediately
in designing the second generation UHR reference implementation, which was the
reason for writing this.
To make
this less magically intuitive and more repeatable, we hope to offer such decision
critieria goodies as a rating system for frameworks or key decisions.
We usually do such ratings intuitively, not in an easily sharable, repeatable
fashion. With a rating system one can compare framework candidate architectures,
vendor offerings, or even compare building an in-house framework to buying one.
This may or may not turn out to be helpful - It all depends on how much of the
essence of frameworks is identifyable into things such as patterns and best
practices.
Best
Practice - A widely accepted good approach to accomplishing something.
For example, some best practices are patterns, frameworks
and democracy. :-)
Compositional
- A feature that allows combining parts or elements to form the whole.
This allows creating larger things from little things. Music and literature
are compositional.
A Compositional Framework is somewhat empty to start with. The designer starts with a blank slate (an empty system) and composes the desired system by adding elements where preferred. This gives the designer great flexibility but requires serious thought. They are for the developer, power user or domain expert. If thy visual tools are raw they are for developers only.
Configurable
- A feature that allows something to be modified by discrete, allowable
changes at various predetermined points. For example choosing the color, engine
and dashboard options of a new car makes the car configurable, though only at
the time of birth.
A Configurable Framework is fairly complete to start with, and may even run. The user configures it for their specific needs, by choosing this and that, entering various required data, and in general filling in the blanks. They are more for non-developers.
Today's Configurable Frameworks are much easier to get up and running than Compositional Frameworks of the same size and domain, because most of the tough decisions have already been made. The two styles are frequently mixed. For example one may compose with parts and then configure each part.
Domain
- A partition of functionality, such as Banking, Receivables, Sorting, Business
Logic, GUI, Communication, Software or Biology. A vertical domain would
be Banking or Receivables, which a horizontal domain would be Business
Logic or GUI. See the diagram in horizontal.
Domain
Neutral - This means something can be used in many domains because
it is "neutral" towards the differences between domains. Domain Neutrality
is important to frameworks because the very idea of frameworks is greater reuse,
and so the more domains a framework can be used on, the better unless undue
tradeoffs occur.
Framework
- A body of software designed for high reuse, with specific plugpoints
for the functionality required for a particular system. Once the plugpoints are supplied, the system
will exhibit behavior that is centered around the plugpoints.
It's interesting that frameworks have only two essential characteristics - the goal of high reuse and the mechanism of plugpoints.
The nature of good frameworks is to embody many best practices and patterns, and make it easy to follow those best practices and patterns, in addition to any domain notions.
The main challenges in framework design are ease-of-use, flexibility to handle different problems or domains and extensibility for planned or unplanned future needs. A secondary challenge is perfomance, which may suffer due to the tradeoff of reuse versus speed. This can usually be overcome with good, flexible framework design, proper framework use design and implementation, and faster hardware as Moore's Law marches on.
The "Design Patterns" book, 1995, pages 26 to 28, has some excellent observations on frameworks. Thanks to Miguel Serrano for pointing out this material and more. Excerpts:
"A framework is a set of cooperating classes that make up a reusable design for a specific class of software.
"A framework dictates the architecture of your application. It will define the overall structure, its partitioning into classes and objects, the key responsibilities thereof, how the classes and objects collaborate, and the thread of control. A framework predefines these design parameters so that you, the application designer / implementor, can concentrate on the specifics of your application.
"The framework captures the design decisions that are common to its application domain. Frameworks thus emphasize design reuse over code reuse, though a framework will usually include concrete subclasses you can put to work immediatesly.
"Not only can you build applications faster as a result, but the applications have similar structures. The are easier to maintian, and the seem more consisstent to their users. On the other hand, you lose some creative freedom, since many design decisions have been made for you.
"If applications are hard to design, and toolkits are harder, then frameworks are hardest of all. A framework designer gambles that one architecture will work for all applications in the domain. Any substantive change to the framework's design would reduce its benefits considerably, since the framework's main contribution to an application is the architecture it defines. Therefore its imperative to design the framework to be as flexible and extensible as possible.
"Furthermore, because applications are so dependent on the framework for their design, they are particularly sensitive to changes in framework interfaces. As a framework evolves, applications have to evolve with it. That makes loose coupling all the more important; otherwise even a minor change to the framework will have major repercussions.
"Frameworks are becoming increasingly common and important. They are the way that object-oriented systems achieve the most reuse."
Framework
Pattern - A pattern that tends to appear only
in frameworks.
Generic
- Reapplyable to different cases. The more generic a software element is, the
more reusable it is. Generic is a frequent synonym for reusable.
Heavyweight
Framework - A framework that provides lots of built in behavior.
They tend to be configurable rather than compositional. Most popular large frameworks
are heavyweight. Examples are SAP and PeopleSoft. There's a spectrum running
from lightweight to heavyweight. An emerging
trend is building heavyweight frameworks on lightweight ones, or even composing
a large framework with many smaller ones.
Horizontal
- In the context of software, horizontal means multiple domains as opposed to
vertical which means one domain. For example many domains can use a relational
database, and so relational databases have horizontal reuse.
Horizontal is preferred to vertical because of wider reuse, if this can be achieved without negative tradeoffs such as understandability, performance, extensibility or feature blandness. :-)
The concepts of horizontal and vertical are frequently used together in describing and designing software. For example:

Here some elements achieve only limited reuse, some achieve vertical or horizontal reuse, and some both vertical and horizontal reuse. Horizontal and vertical reuse goals are a crucial part of framework design. The greater the reuse goal, the more difficult the design. To make both horizontal and vertical reuse easier, one should build frameworks on frameworks. This lets the lower frameworks achieve the widespread reuse (such as both horizontal and vertical), while the higher frameworks achieve limited (such as only vertical) but very effective reuse.
Layer
- A system partition in a "stack" or "string" of partitions.
A stack example is GUI, Business Logic, Persistence. A string example is client
object, communication, firewall, server. Layers are A Good Thing. They allow
clean system organization and controlled inter-layer collaboration. Layers are
used in Layered Architeture. A layer is also a synonym for horizontal
domain.
Lightweight
Framework - A framework with very little built in behavior. They
tend to be compositional rather than configurable. For example all it may provide
is the ability to organize classes, create instances, start and close the system,
and let plugpoints collaborate. Examples are Applets and Servlets.
Pattern
- A reusable solution to a design problem. It is usually abstracted in a model
and implemented in code or declarative knowledge. See much more.
When a pattern is followed via designing classses to express it, that's not a framework. But when reusable classes allow a pattern to be designed and implemented easily, that's a pattern framework. This could be done with interface plugpointss, abstract classes, deliberate subclassing, parameters, etc. This could be a pattern as small as a Registry (one interface for items and one class, the registry) or as large as Layered with Services.
Plugpoint
Framework - A impressive synonym for a framework, since all frameworks
have plugpoints. See primitive earlier writeup. :-)
Reuse
- The practice of building something once but using it in many different contexts.
The more that context can vary, the higher the reusability. See earlier writeup.
System
- A group of things working together to accomplish common goals and offering
complete functionality in an area. Unlike a subsystem, a system can "stand
alone".
A subsystem is a group of things working together to accomplish common goals, but requiring other systems to accomplish its work and/or be useful. A system is composed of subsystems, which are composed of subsystems, etc.
A system framework is usually larger than a subsystem framework, and has different goals. Significant system frameworks tend to offer component lifecycle management, system composition, services, collaboration mechanisms and tools. Subsystem frameworks are much smaller, tend to cover a limited domain, and are much easier to design. Both types can be domain neutral, such as collections, sorting algorithms or somewhat CORBA. However most frameworks are domain specific.
A subsystem often appears to be a system because we ignore the other systems it needs. For example a database application is usually called a system, despite its need for hardware, communication lines, middleware, electricity, users, administrators, etc. Thus the distinction between system and subsystem is blurred. The common use is to say "system" for everything unless speaking in a relative sense, when "system" and "subsystem" make sense. In the final analysis, all systems are subsystems except the universe. :-)
In software a system is two or more collaborating objects. Thus most systems are subsystems, like security, comm, GUI, a complex algorithm like compression, etc. For a small system a framework may provide something as simple as a reusable approach to MVC, plugpoints for algorithm variation, an umbrella of abstract classes for GUI widgets, etc. For a big system a framework may be something like CORBA, EJB, or a domain specific client/server framework with hundreds of plugpoints and options. Frameworks vary vastly. Large systems frequently layer frameworks on frameworks. The important thing is reuse of expertise.
Vertical
- In the context of software, vertical means one domain as opposed to horizontal
which means multiple domains. For example a product in the word processor vertical
market may use a spell checker. The spell checker is also used by email, report
generator and instant messaging products, which makes the spell checker a horizontal
product. See discussion in horizontal.
Quiet. Thinking in progress. Let me whisper a secret to you: "The essence of frameworks may require the essence of software!" To avoid that rather large job, we will try, try to focus on just frameworks.
How have other fields expressed their essence? With fundamental elements and laws. Software barely has any of these. As the book "Who Got Einstein's Office" says on page 260, "Ed Witten divides the history of superstring theory into three distinct periods which he calls 'Incredibly Primitive', 'Very Primitive' and 'Probably Still Primitive'". Software is somewhere down here. :-)
Here's a few rough thoughts:
Do experiments, stop philosophy! Mine past efforts. For example compare systems with the same requirements - what differs to explain the better way?
What would a fundamental element look like? What would a law look like? It would have fundamental elements and relationships which were true. This may lead to understandings about software, but that's Big Stuff. We focus on a subset, frameworks with laws like:
This mumbo jumbo was leading nowhere. However the last 2 ideas were promising, so we pursued them in a completely different direction that just might get somewhere. See essay on The Essence of Frameworks.
Good large frameworks will exploit most or all of the Framework Patterns, except the infrequent ones. The absence of a pattern in a large or crucial framework should raise the question, "Is the need for this pattern present?" If the answer is no, try "Will the users of the framework need the advantages this pattern provides in the future?" or "Should the need be there?" If the answer is yes, the next question would be, "Does the framework resolve the need in a better way than this pattern?" which is entirely possible.
There are many other patterns besides these Framework Patterns appearing in most frameworks, such as Layered, Fascade, Mediator and Event. The presence of these, when used well, is a good sign.