Frameworks

Created 9/19/99 - Last Updated 9/24/99 - Jack Harich - Go Back


Objectives

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.


Framework Glossary

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.


The Essence

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:

  1. The smaller the core, the more poweful the framework.
  2. All frameworks have plugpoints.
  3. The smaller the number of conceptual methods, the more reusable a class is.
  4. The greater the ratio of reuse, the more fundamental the reusable must be.
  5. Plugpoint Structure behavior can be mostly but not completely expressed as self referential parts. The irreducable remander is a primordial non-part.
  6. Thus life must come from life. Non-trivial programs can only be built from other programs.

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.


Evaluation

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.