Why is it that so many people want to write frameworks (rather than using them)? Is it the “Hey, I’ve just written a method that makes sense in another application! Why not make it a framework? That’s so much more fun!“-effect? Or the “We have a bunch of applications that we need to migrate. Let’s begin with a framework to ensure they are build consistently“-demand? Does “not invented here” still play a role?
Well, any of these and other motivations probably plays its role and is more or less wrong or right, depending on the situation. I’m not going to judge this in general. But there is another question that should in all honesty be asked: Why are there so many bad frameworks out there? I.e. frameworks that do not meet the requirements?
Note that “bad frameworks” does not imply “bad code”. The framework code may be at the edge of geniality, yet if the requirement was reuse and noone actually did reuse it, then it missed the requirement. If it was meant to hide complexity and ease the usage of certain things but all it did was replacing one complex task with another, then it failed. Even if it met all requirements, yet it caused overly complex and non-maintainable client code, I would regard it as failure.
Sadly many bad frameworks are written by good developers for their best. I have written bad frameworks, no kidding! (Of course I don’t do that anymore… 😉 .)
The main reason for this phenomenon may be due to one single fact that is too often overlooked: Just as frameworks differ from applications, framework development differs from application development. And the single most differentiating point between applications and frameworks is the user base. The users of a framework are other developers. In the same way a usual application supports the end user (think of usability, consistency, appearance, etc.) a framework has to support the developer.
In his article “Framing the framework conversation” Jack Vaughan lays his hands right into the open wound: “Application frameworks have been around for a while now, but accepted best practices in application framework building still seem to be something of a new thing.”
Jack also says “One worst practice to avoid in framework creation is to look at the application framework in the same way as a typical IT application.” And later on “An obvious but sometimes overlooked point: Developers are the people that will be “using” this framework software.”
Just my point, right?
Enough bashing, let’s get a bit more constructive. I have also written some very good frameworks (again, “good frameworks” simply stands for “frameworks that met the requirements”), and here are some golden rules I learned from experience:
1. Focus on the “user interface”, not on the functionality
2. Robustness is of utmost importance
3. Align the framework with existing environments and standards
Just as Asimov was not content with with his “Three Laws of Robotics” and prepended law #0 I like to add the following:
0. Know when not to write framework code.
Of course I’m not going to raise the natural radiation level to render mother earth uninhabitable. Promise.
In more detail:
1. Focus on the “user interface”, not on the functionality
When you begin developing a framework, start with writing the client(!) code, including any configuration, as if this framework already existed.
This way you will not only specify the functions provided by the framework, you will specify the interface the framework shall provide. This covers not only the functional demands, but the “ergonics” in using it. In other words, you’ll have a fairly complete specification of the user interface of your framework, i.e. the API, configuration file schema, and even encountered behaviour (such as exceptions).
This approach makes sure the framework can be leveraged with as little effort as possible. This also implicitely includes what should not be necessary to use the framework. E.g. some module concerned with exception handling might have to register the necessary eventhandler itself rather than expecting the user to do this, or worse yet, expecting him to cover his code with try/catch.
Focusing primarily on the functionality, the framework will probably fullfill the requirements as well. Yet in order to use it the user will have to write a lot more unnecessary and tedious code. Perhaps he will even have to deal with internal details, thus contributing to the breaking changes of your next version.
2. Robustness is of utmost importance
Framework users have much more options to stress framework code than endusers have with applications. Thus framework code needs to be much more robust than common application code. You never know under what conditions and in what contexts your framework code will run. If some error occurs, don’t expect “sympathy of a fellow developer”, people using a framework are as demanding and unforgiving as any other user.
Things you should think of include:
- Extensive checks of all information comming into the framework: call parameters, configuration data, connection objects, various contexts (request, transactions, security, …), …
- Possibly special configuration checks during initialization. e.g. if the configuration points to a directory (or any other resource that is uncertain to exist or subject to security restrictions), try accessing that directory right away; if it contains a type for dynamic object creation, create it now.
- Use reasonable default values to avoid effort on the users side. The less work the user has to do, the more pleased he will be – not to mention the less chances for mistakes.
- Provide meaningfull error messages. Don’t tell the user an error happend (he’ll know that anyway :-)), tell him how to solve it. A NullReferenceException doesn’t help at all to find the problem, some kind of configuration exception with the setting name and a hint why it caused an error does.
3. Align the framework with existing environments and standards
Work with the .NET Framework and Visual Studio. Leverage and enhance them. Use similar patterns and conventions. Behave like a good citizen who is just trying to help.
This way you will realize the most synergy effects for the users:
- You build on already present concepts and knowledge (which also streamlines your documentation)
- You achieve better reuse effects if you can plug in an already existing infrastructure
- You will participate in future enhancements of the platform
If you started developing parallel or even contradictory concepts for things already there you would allways have to to justify yourself, cope with improper usage, and generally bad acceptance among your user base. (You would be seen as an anarchist rather than a good citizen.)
Personally I adhere to this rule as long as possible, even if my own solution appears to be better. I would even drop framework features if the new version of the environment suddenly provides something similar. Which is an ideal transition to the next point…
0. Know when not to write framework code.
There are different reasons for not writing framework code, yet the most important one is: The feature is already available somewhere else.
If Microsoft has done it, use it. If there is a serious community project, use it. If someone in another department did something similar, go drink a coffee with that guy.
Face it: Any big company that sells a product is far better at developing, documenting, maintaining this product. Any community will constantly contribute to and reassess framework features, as well as use and test it in very diverse contexts. Who thinks he can cope with that on his own, especially in the long run?
Of course they might fail. So what? They are less likely to fail than you and they are ar far better target to blame if they do.
At the end of the day…
… your framework will still have to deliver some functionality. But following these guideliness should make your users happy for the features, rather than frustrated because of the stunts needed to access them.
Some additional hints:
- The article “Framing the framework conversation“, Jack Vaughan, inspired this post when he confirmed some lingering thoughs I had. It also has some additional links and hints.
- Although I haven’t read it (yet) a collegue of mine (whom I hold in high regard) recommends “Framework Design Guidelines” and the blog of one of the authors “Krzysztof Cwalina“.
- Any book on wellknown patterns or code quality will help, e.g. the classic book “Design Patterns: Elements of Reusable Object-Oriented Software” or (one of my favourite books) “Code Complete“.
Disclaimer: While Jacks article inspired this post and some fellow collegues unwillingly contributed to it 😉 , it is solely based on my own experience. Blame me for any mistakes and for not honoring some people’s efforts. 😀
[…] Very nice article. And author’s blog is interesting too […]
Pingback by Software development Blog Digest - Frameworks - don't let 'em frame you! — October 29, 2006 @ 8:11 am
[…] Frameworks – don’t let ‘em frame you!, by Alexander Jung […]
Pingback by Write the Client Code First : Ray Morgan — June 1, 2009 @ 4:34 am