2. The Beauty of Simplicity
How can you prevent your framework from becoming unmanageable?
You have come to the conclusion that building a framework in your project is justified. Several applications are going to be developed and it’s clear that they will benefit from the framework. You are now in discussions with the potential framework users about what functionality the framework should cover.
Obviously, the application development teams will come up with requirements for the framework. After all, they are supposed to use the framework, so the framework better meet the requirements they have. However, application developers are sometimes inclined to place more and more requirements on the framework; greater functionality offered by the framework means more time and effort the application development teams can save.
Moreover, framework developers sometimes flirt with wanting to build the perfect framework. Just one more abstraction here, and another generic parameter there, and the framework can grow incredibly powerful.
All these things easily lead to the framework’s architecture becoming rather complex. However, there is much danger in complexity.
First, a complex architecture is difficult to build, maintain, understand, and use. Excessively complex frameworks can therefore create a challenge for designers and users alike, perhaps more of a challenge than they can meet.
Second, complexity, in the context of framework development, often means additional abstractions that are often reflected by generic algorithms and data structures. Genericity, however, is often the enemy of efficiency, and too many abstractions can easily lead you into efficiency problems you cannot resolve.
Third, the more complex the framework is, the longer it takes to build it. If the framework is supposed to "solve all problems on earth," it won’t be available anytime soon.
This, however, is unacceptable. You don’t have much time to build your framework. The teams that build the applications rely on the framework, and they won’t be willing to wait for you. A specification of the framework has to be available when the other teams start designing, and a first version of the framework has to be completed before the other teams start coding. If you don’t manage to get the framework ready in time, this will turn out extremely expensive for the entire project.
And no, you cannot rescue the situation by adding more people to the framework team when the deadline is approaching and the schedule is getting tight. We all know that adding people to a late project makes the project later [Brooks1995].
Design your framework to be small and to focus on a few concrete tasks.
Try to limit the scope of the framework to what is truly necessary:
- Focus on a small number of core concepts. Avoid too much abstraction. A framework that embodies too much abstraction tries to do too much and is likely to end up doing little.
- Perhaps your framework can be a framelet [Pree+1999]. A framelet is a very small framework that defines an abstract architecture that’s not for an entire application but for some well-defined part of an application. It follows the "don’t call us, we’ll call you" principle, but only for that part of the application.
Much in the vein of agile development methods [Ambler2002][Cockburn2002], try "the simplest thing that could possibly work" [Beck2000]. Go with a small solution that works, rather than with a complex solution that promises more than it can deliver.
The Data Access Layer Framework
When assembling the requirements for the database access framework, the team had to work hard to exclude any application logic from the framework. Many applications were going to use the framework’s versioning features, but all had different ideas on how to use them. The team had to fight to avoid a versioning system that could be used in many different modes. Had the framework team agreed to include all the features that some of the other teams desired, it would have blown up the framework to incredible proportions.
In order to not overcomplicate the framework, the team also had to restrict the mapping of logical entities onto physical tables. Only simple mappings were possible; advanced techniques such as overflow tables had to be left to the applications. Generating the database access functions would otherwise have become unmanageable.
Nonetheless, the data access layer framework did suffer from too much complexity. The composition of business objects from smaller entities turned out to be extremely complicated. The team managed to implement it properly in the end, but only after much unexpected work. In addition, this complexity made the framework more difficult to use than had been intended. Looking back, the team felt the framework should have done without this mechanism, which required much effort and did little good.
To summarize, the team was successful in keeping the framework simple in many instances but felt they should have made simplicity an even more important issue.
The Web Portal Framework
Providing a portal infrastructure is a concrete task, and certainly one that can be addressed by a framework. Like so many other frameworks, however, this Web portal framework suffered from becoming too powerful and, as a consequence, too complex. For instance, parameters need to be passed between the Web browser and the applications running on the mainframe, and the framework includes a mechanism that manages parameter passing in an entirely generic way. It’s powerful, but it’s difficult to understand and rather inefficient. A simpler mechanism would have been better.
But there is a success story as well. The framework wasn’t only supposed to provide an infrastructure for the Web portal; it was also supposed to provide one for integrating Web services (which don’t expect results from the applications to be represented as HTML). The framework team managed to meet these requirements in a simple and elegant way. The framework features a layered architecture: presentation issues are dealt with only in the servlet engine, while use-case management is concentrated on the application server layer. Web services can use the application server layer exactly as the portal does and simply not make use of any HTML generation.
Reducing a framework’s complexity is a strategy generally approved of in the literature. For instance, Art Jolin recommends that frameworks be simple and modeless [Jolin1999]. And in our particular context—time constraints along with framework and application development happening simultaneously—keeping the framework simple was crucial.
Simplicity also contributes to longevity. For instance, Brian Foote and Joseph Yoder propose The Selfish Class [Foote+1998]—a class that represents an artifact that reliably solves a useful problem in a direct and comprehensible fashion. In a similar vein, a framework that focuses on a set of core abstractions has a relatively high ability to evolve gracefully and therefore stands the best chance for longevity [Foote+1996].
In order to keep the framework simple as the project goes on, you must be careful with change requests that other teams might have, as they might introduce more, and unwanted, complexity. As a general rule of thumb, only accept Multiple Change Requests (8)—change requests that are made by several, at least two, application development teams.
And of course a Skilled Team (3) is critical to keeping the framework simple. Framework development requires a team that is aware of the problems complexity brings and that is able to see the beauty of simplicity.