.NET Framework Design Guidelines (Book Review)

I believe that good technical books fall roughly into 3 categories:

  1. Required reading now but throwaway later: these books go out of date quickly (for instance, that thick copy of plain ASP 3.0, which is now almost completely useless!)
  2. Essential, technology agnostic, lifespan of more than 10 years: containing advice which applies across the board regardless of technology, language or version. These are often process related books. Examples of books in this category are “Code Complete”, and the excellent, recently released “Head First OO A & D” (review to follow shortly).
  3. Essential, technology specific, lifespan hard to measure due to possibility of rapid technology shifts: vital books targeted at some specific technology or language.

The Framework Design Guidelines by Brad Abrams and Krzysztof Cwalina falls mainly into the last category, but also overlaps somewhat with the second.


Who should read this book?

Architects, API and Framework designers, lead developers, junior developers who want to be senior developers(!). Basically, anyone who is designing frameworks or writing code targeting the .NET framework.

The book is divided into 9 chapters and 3 appendices. The guidelines are presented in 4 major forms: Do, Consider, Avoid and Do Not. The authors choose a single language for the examples (which are in C#), which rather being a snub to VB.NET developers is rather more of a complement, as they mention they wanted the book to appeal to the widest audience. A DVD is also included containing several hours of video presentations.

This book represents the condensed wisdom and best practices of literally hundreds of developers, and a number of well known and respected, industry heavyweights have annotated the book, providing discussion and reasoning behind the guidelines.

1. Introduction
This chapter is a brief introduction and discusses the qualities of a well designed framework and the philosophy behind the design. In summary, frameworks are: simple, expensive, full of trade-offs, borrow from previous designs, are designed to evolve, are integrated and last but not least, are consistent.

2. Framework Design Fundamentals
Offers principles and guidelines central to framework design. Talks about scenario-driven design (very similar to TDD), having a low barrier to entry, self documenting wherever possible, the principle of layered architecture, API usability studies.

3. Naming Guidelines
Consistent and accurate naming is an essential principle of designing and writing all code. Krzysztof writes: “The team that develops the .NET Framework Base Class Library spends an enormous amount of time on naming, and considers it to be a crucial part of framework development.” As a consultant, poor method naming is something I see often. As Steven Clarke notes, methods should be named according to what they do, not according to some implementation detail.

4. Type Design Guidelines
This chapter provides general guidelines for the design of types and covers some of the associated subtleties and tradeoffs. This is a heavily annotated chapter, brimming with excellent advice.

5. Member Design
This is one of the slightly longer chapters (57 pages), and follows on from chapter 4, covering basic guidelines that should be followed when designing members of any type. It covers the design of properties, constructors, events, fields, operator overloads, and parameters. I seem to learn something new each time I re-read this and the preceding chapter.

6. Designing for Extensibility
How do you ensure that your framework will be extensible and stand the test of time? This chapter covers unsealed classes, protected members, events and callbacks, virtual members and abstractions. The annotations in this chapter contain several gems of advice, including determining the trade off of extensibility versus performance and some of the subtleties of creating types with virtual members.

7. Exceptions
This chapter is surely the definitive reference for exception handling. It covers the reasoning and benefits behind using exceptions and the best practices in creating and using them within frameworks. Required reading for all developers. [David M Kean posted excellent advice on which exceptions to raise here.]

8. Usage Guidelines
This chapter covers guidelines for the use of common types in publicly accessible APIs, implementing common interfaces and extending common base classes.

9. Common Design Patterns
Chapter 9 does not cover the subject of design patterns in general; rather it discusses a limited set of patterns that are frequently used in the .NET framework.

Conclusion
There is little doubt that a few paragraphs can adequately capture what is contained in the Framework Design Guidelines, or the amount of cumulative effort that has gone into producing this distilled wisdom. If you are a serious .NET developer then you should definitely have access to a copy of this must-read book.

My favourite quotes from the book:
“I have always felt that a key characteristic of a framework must be consistency”, Anders Hejlsberg in the foreword.

“Frameworks must be designed starting from a set of usage scenarios and code samples implementing these scenarios.”

Be Your Own Client

Don Box posted that Chris Sells has long been an advocate of ‘Be your own client’.

This approach is not just suited for API design, but for just about any design task, especially user interaction.

Great CSS Techniques

I recently purchased “The Zen of CSS Design” by Dave Shea and Molly Holzschlag and I would highly recommend it to any web designers or graphic artists working in the area of web design. You can visit the accompanying site CSS Zen Garden which is “A demonstration of what can be accomplished visually through CSS-based design”, and tries to address “the need for CSS to be taken sereiously by graphic artists.”

I also came across this link to a collection of excellent CSS techniques to solve common design tasks. Well worth book-marking: 53 CSS-Techniques You Couldn’t Live Without

If you are interested in this topic you should check out the recently released CSS Control Adaptor Toolkit from Microsoft, which basically enables ASP.NET 2.0 controls, which normally render as HTML markup, to be emitted as pure CSS based output. Scott Guthrie has a quick introduction to what they are and how they work here.

UPDATED: I also came across the CSS Handbook site. Also, check out this CSS cheat sheet.

For discussion on the pros and cons of Table versus CSS layout see Bill Merikallio and Adam Pratt’s Why tables for layout is stupid. There’s a more balanced look at the two approaches at Tables vs. CSS: PROS and CONS. (saw this via Scott Mitchell over at 4GuysFromRolla)

What Would You Do Next?

Darren Neimke posted an interesting question on a situation many developers/managers find themselves in. I’ve quoted it in full below:

You’ve just joined a new company as a senior developer. During the interview process your role was discussed in depth…

1. Lead a development team
2. Deliver a new application
3. Using state of the art tooling
4. Highly ambitious

You start, and in your first few days you are shown more details of the task at hand. The project plan and delivery timeline were created by the head developer – a person for whom you have a great deal of respect. Internally you are no really about how you will deliver this in such a short space of time.

What do you do next?

Even though Darren posted this over a week ago I thought I would chip in with my 2 cents worth and attempt to answer some of these questions, beginning with a few of my own:

Does point #3, do you mean that there is little experience with a new set of tools? Are these tools stable, well documented, well supported? Are we talking about VS2005 Team System?

Point #4: In what way is the project “Highly Ambitious”? For the customer? For the developers? Does this mean it consists of too much scope in an undoable timeframe? If so, it’s time to start pruning non-essential features.

How would you establish that the existing project delivery plan is realistic?

First thing I would do is take a look at the requirements (hopefully, you have some). Talk to the customer, and make sure you understand what they are trying to achieve; in other words, get an understanding of their target domain and how this software will make their task easier/more productive and what the essential features are (“The high level feature list”). If you are going to sign up for, and be responsible for a project delivery plan, then you should verify that what is being asked is achievable.

“Get the feature list from the customer, and then figure out the requirements you need to implement those features”

Next up, do you have a set of use cases (scenarios) describing the high level processes that the application is supposed to perform? This is a excellent way of determining if the features are all supported and the requirements are complete, or if there are there surprises lurking.

“scenario” is often used interchangably to mean one of the following:

  1. a use case
  2. a path through a use case
  3. an instance of a use case

#2 and #3 are really the same thing. #3 is preferred (more than one scenario occurs when the use case has alternate paths, but these still achieve the main goal of the use case)

Each use case must have:

  • clear value to the system
  • a well defined start and stop point
  • an external initiator

As soon as you have a set of use cases, you can perform textual analysis upon them to figure out candidates for your classes and methods (nouns and verbs). By this point, you should have enough information to break up your application into smaller pieces of functionality, and have a better handle on how much development time is required.

Grant Halliday’s comment about working 20 hr days is a little worrying! 😉 If any developer is working more than 8 or 9 hours a day, then you have a big problem. Odds are they will be making plenty of mistakes. There is considerable evidence to back this up. A good plan will not force developers to work unproductive hours. Any manager that thinks he will retain the confidence and support of his staff in doing so, is almost certainly mistaken.

A Little Gem of a Book: “The Elements of C# Style”

Here is some condensed wisdom for C# programmers from a ‘must read’ book, The Elements of C# Style. This book models itself in the tradition of “The Elements of Style”, and is a similar physical size, which means you can easily read it cover to cover in very little time.


If you program in C#, having a copy of this book on hand will provide a great reference, at least until you commit it all to memory! Some of this sage advice applies to other languages as well:

  • Use meaningful names. Names things accurately and consistently
    With the exception of loop variables used as a counter or index within a loop (where using ‘i’ is often more readable than a longer name).
  • Use names that exist in the terminology of the target domain
  • Do not use excessively long names or excessively short names
  • Do not shorten names by removing vowels; use complete words
    It’s not the 1970’s! Your compiler is not going to complain about names longer than 32 chars (Oracle might though!) Take this along with the previous suggestion.
  • Avoid abbreviations unless the full name is excessively long
  • If you really have to use an abbreviation, use one that is widely used and commonly accepted.
  • Pluralise the names of collections
    List cars = new List();
    Car car = cars[index];
  • Prefix interface names with “I”
  • Use nouns to name interfaces that describe service declarations
    public interface IMessageSink
    {
    public void MessageReceived();
    }
  • Use adjectives to name interfaces that describe behaviours
    Most of these will end in –ible or –able.
    public interface IDriveable
    {
    public void Drive();
    }
  • Add a suffix of “Base” to abstract base types
  • Add a suffix of “Exception” to custom exception types

I did find a couple of typographic errors and one bit of advice which is considered wrong if you go with the recommendations in the Framework Design Guidelines by Brad Abrams and Krzysztof Cwalina; namely, point #157 states that you should derive custom exceptions from ApplicationException. These should be derived instead from System.Exception.

Also, quite by coincidence, on a second re-read I noticed that the double-lock pattern used in point #85, should not be used (see my previous blog post which refers to Jon Skeet’s article). Jon mentions that it can be fixed using memory barriers via the volatile keyword, which in this particular example would require the instance of LoanCalculator to be declared as volatile. But, he also mentions that the experts can’t agree on this, and is therefore sensibly avoided!

I believe point #48 should read:
[MyFavouriteAttribute]