Bearing these definitions in mind, a number of properties arise from a well-designed framework.
A framework defines the behavior of a collection of objects. It provides ways of reusing analysis, design and code and includes a set of software building blocks that programmers can use, extend, or customize for specific computing solutions. These building blocks usually make up a library of subclasses.
A framework, though, is more than a well-written class library, it is an abstract specification of a kind of application. Libraries reuse code but little analysis or design. A class library does not enforce a particular design on an application, it just provides functionality that can help the application to do its job. Nevertheless, some libraries exhibit framework-like behavior and some frameworks can be used as class libraries. It can be seen as a continuum with traditional class libraries at one end and sophisticated frameworks at the other.
With frameworks, developers don't have to start from scratch every time they write a particular application. Frameworks help developers provide solutions for problem domains and better maintain those solutions. They also provide a well-designed and thought out infrastructure so that when new pieces are created and added, they can be integrated with minimal impact on other pieces of the framework [Nelson, 1994].
No matter how elegant and well-designed a framework is, it won't be used unless the cost of understanding it and then using its abstractions is lower than the perceived cost of writing these functionalities from scratch, without using the framework [Booch, 1994a]. It is important to remember that Software is not reusable until it has been reused [Johnson, 1993].
To be successful, a framework must be complete, flexible, extensible, and understandable [Taligent, 1994]. A framework should also observe ways of minimizing potential client errors and enhance platform portability. It should be illustrated with examples. Examples make frameworks more concrete and make them easier to understand [Johnson, 1992]. As a matter of fact, a framework is just a generalization of preexisting examples in a particular application domain. An example of a framework is a use case.
Frameworks impose a model that the the developer must adapt to. But on the other hand frameworks improve developer productivity [Moser and Nierstrasz, 1996].
The goals of framework design should be to build applications from preexisting components, use a small number of types of components over and over and write as little code as possible (ultimate goal is no-code: build programs by direct manipulation) [Johnson, 1993]. With a framework it shouldn't take a good programmer to build a good program. Frameworks are designed by experts in that domain but can then be used by non-experts.
A framework usually plays the role of the main program in coordinating and sequencing application activity and flow control. In a framework, the main program is reused, and the developer decides what is plugged into it and makes new components that are plugged in. The developers code gets called by the framework code. The framework determine the overall structure and flow of control of the program [Johnson, 1997].
Frameworks are related to designing components. When designing a component we also have to trade simplicity for power. A component with many parameters can be used often but will be hard to learn [Johnson, 1997].
Finally, a framework reuses analysis. It describes the kinds of objects that are important and provides a vocabulary for talking about a problem. An expert in a particular framework sees the world in terms of the framework, and will naturally divide it into the same components. Two expert users of the same framework will find it easier to understand each others designs, since they will come up with similar components and will describe the systems they want to build in similar ways [Johnson, 1997].