다음을 통해 공유


Design Guidelines Book (The Principle of Scenario-Driven Design)

The Design Guidelines have been published on MSDN and as a part of the CLI ECMA specification (Partition V, Annex D). This was long time ago and we have been receiving lots of requests for an update and also for something that can be read offline.

So, here you go -- Brad and I have started working on a Design Guidelines book. It’s going to include new guidelines we added since we published them on MSDN, cleanup existing guidelines, add justifications, examples, and annotations from industry experts.

I thought I would share with you a small section of a chapter that talks about fundamental principles of API design. This particular principle is one of my favorite.

Please keep in mind that this is a draft form and also part of a bigger context/chapter, so some things may not be as clear as in the final version.

The Principle of Scenario-Driven Design

Frameworks often contain a very large set of APIs. This enables advanced scenarios that require power and expressiveness. However, most development revolves around a small set of common scenarios that use a relatively small subset of the full framework. To optimize the overall productivity of the developers using a framework, it is crucial to invest heavily in the design of APIs that are used in the most common scenarios.

Therefore, framework design should be focused around a set of common scenarios to a point where the whole design process is scenario-driven. We recommend that framework designers first write the code that the users of the framework will have to write in main scenarios, and then design the object model to support these code samples.

Framework Design Principle: Frameworks must be designed starting from a set of usage scenarios and code samples implementing these scenarios.

Annotation (Krzysztof Cwalina):

I would love to add “There is simply no other way to design a great framework” to the text of the principle spelled out above. If I had to choose only one design principle to be included in the book, this principle would be it. If I could not write a book but only a short article on what’s important in API design, I would choose this principle.

Framework designers often make the mistake of starting with the design of the object model (using various design methodologies) and then write code samples based on the resulting API. We assert that a list of scenario with code samples and a header-style object model description work best for public API design; commonly used object-oriented design methodologies are not optimized for API design.

Object-oriented design (OOD) methodologies (e.g. UML) are optimized for the maintainability of the resulting implementation, not for the usability of the resulting APIs. They are best suited for internal architecture designs—not for designs of the public API layer of a large framework. Framework design is not something many people do. Because of that, there is no well-established design methodology for API design. Some of the practices described here can be seen as a rudimentary form of such a methodology.

Teams developing frameworks should start with producing a scenario-driven API specification. This specification can be either separate from the functional specification or can be a part of a larger specification document. In the latter case, the API specification should precede the functional one in location and time.

The scenario section should list the top 5-10 scenarios for given technology area and show code samples that implement these scenarios. The code samples should be in at least two programming languages. This is very important as sometimes code written using those languages differs significantly. It is also important that these scenarios be written using different coding styles common among users of the particular language (using language specific features). The samples should be written using language-specific casing. For example, VB.NET is case-insensitive, so samples should reflect that. C# code should follow the standard casing described in the naming section of the Design Guidelines.

2.1.1.1 Usability Studies

Usability studies with a wide range of developers are the key to Scenario-Driven Design. The code samples written for the top scenarios may seem simple to their author, but might not actually be that simple to other developers. Additionally, understanding the way that developers approach each of your scenarios will provide useful insight into the design of the framework and how well it meets the need of all target developers. Because of that, conducting usability studies of the top scenarios is a very important part of the design process. If the majority of developers cannot implement one of the scenarios, or if the approach they take is significantly different to what the designed expected, the API should be redesigned.

The API usability studies should ideally be performed using the actual development environment with intellisense, code editors, and the documentation most widely used by the targeted developer group. However, it is best to run usability studies early rather than late in the product cycle, so don’t postpone organizing a study just because the whole product is not ready yet.

þ Do make sure that the API design specification is the central part of the design of any feature that includes a publicly accessible API.

þ Do define top usage scenarios for each major feature area.

The API specification should include a section describing the main scenarios and show code samples implementing these scenarios. The section should appear immediately following the executive overview section. The average feature area (such as file I/O) should have 5 to 10 main scenarios.

þ Do ensure that the scenarios correspond to appropriate abstraction level. They should roughly correspond to the end user use cases.

For example, reading from a file is a good scenario. Opening a file, reading a line of text from a file, or closing a file are not good scenarios; they are too low-level.

þ Do design APIs by first writing code samples for the main scenarios and then defining the object model to support the code samples.

þ Do write main scenario code samples in at least two different languages (for example VB.NET and C++).

ý Do not rely solely on standard design methodologies (for example UML) when designing the public APIs layer of a framework.

Scenario Driven Design together with prototyping, usability studies, and some amount of iteration is a much better approach.

ý Do not start API design with object model diagrams.

Object model diagrams of the main object-oriented design methodologies are optimized to produce implementations that are easy to maintain, not to produce APIs that are easy to use.

þ Do organize usability studies to test APIs in main scenarios.

The studies should be organized early in the development cycle as the most severe usability problems often require substantial design changes. Most subjects should be able to write code for the main scenarios without major problems; if they cannot, you need to redesign the API. While this is a costly practice, we found that it actually saves resources in the long run. The cost of fixing an unusable API without breaking changes is enormous.

Comments

  • Anonymous
    May 08, 2005
    Hmmm, sounds like (T)est (D)riven (D)esign :)
  • Anonymous
    May 09, 2005
    Having a book getting written on this subject is definitely good news!
    As a long time Design Guidelines reader and spreader, I think this subject will become even more important now that so many people are (and will be) designing APIs for consumption via Web Services. Not that a local assembly doesn’t also deserve such attention.

    Things I would like to see covered:

    - API Usability Testing
    - What it is.
    - How it is done
    - Tools (even if with spreadsheets, forms, etc)
    - Global API design naming conventions
    - Names in foreign languages
    - Non-ASCII 7 bit characters usage
    - Stories on design decisions and changes made on .NET since prior to the version 1.
    - Examples of good and bad decisions on FCL 1.0, Everett, Whidbey and maybe a glimpse on Orcas.
    - Breaking Changes
    - How to minimize the need for
    - How to do them when needed
    - Web Services
    - XML Schemas
    - Mockup techniques - How to use IDEs so early?
    - Progressive APIs. What they are and how to design them.
    - Exposing auto-generated code in public APIs (Maybe not a good idea)
    - Designing for performance
    - Versioning
    - Security (threat models, etc)
    - Using tools such as FxCop, UML, etc.
    - Naming database objects.
    - This is coming more important each day since tools are becoming more and more used to auto-generate objects in various tiers and maintaining a consistent naming when possible is an important issue.
    - Name mappings when it is not possible or desired a direct naming correspondence.
    - API review process
    - Committee, workgroup, single person?
    - Roles
    - Skills needed

    Probably I forgot a dozen of other topics I’d like to see covered.

    Do you already have an overview of what is going to be covered?
  • Anonymous
    May 11, 2005
    Krzysztof spilled the beans… He and I are working on bringing all the goodness of the Framework Design...
  • Anonymous
    May 13, 2005
    Thanks very much for sharing your insights on the scenario-driven framework design! You and your team are doing a great job providing .NET framework best-practices and guidelines to the developer community!

    In this post, you are referring to a scenario-driven API specification. How would a typical document look like? Is there any available template that a framework API designer could use? Or would an MSDN-like API-documentation be sufficient to start with? Also, is there anything special about the functional specification when designing a framework as opposed to design of an application.

    Thanks in advance!

    P.S. The design guidelines book is a great idea!
  • Anonymous
    May 13, 2005
    Adam, I think it's similar to TDD (test/tutorial driven design), but I would say SDD has slightly different motivation and is lighter weight.

    Alfred, it's a great list of questions/topics to either cover in the book or in the blog. I started with a post with some pointers to usability study resources. See http://blogs.msdn.com/kcwalina/archive/2005/05/13/417240.aspx.

    George, I have good news for you. I am trying to get an appendix added to the book that would contain a sample API specification that we used to design a simple Framework API (Stopwatch).
    As, to designing APIs for apps vs. frameworks, there are some differences. They get larger if the app interfaces are not publicly exposed and get smaller for public app plugin APIs. The main reason is that framework APIs really cannot be changed after they ship. Other differences stem from the fact that usual application APIs (even public) usually are used by smaller group and less diversified group of developers (this is a generalization but on average this is true). Anyway, this is a big topic in itself. I will put it on my "to blog" list.
  • Anonymous
    May 16, 2005
    Something along these lines that I would like to see, is VS project and item templates to simplify applying these design guidelines. For example, a sample of the above scenario-driven design doc could be included in the class library project, or as a sub-item to a class item. In VS2005 this should be a good deal easier.
  • Anonymous
    August 05, 2005
    Oh, what a great day… I just finished doing the final page proofs for the design guidelines book that...
  • Anonymous
    May 23, 2006
    Hi.

    I had a look into the book's TOC at Addison Wesley website. What I'm missing are naming guidelines for ASP.NET, especially for classes inheriting System.Web.UI.Page and System.Web.UI.UserControl, the types which have related as?x files. Maybe you can tell me what is the best way for naming this example type:

    a)

    public class UserPage : System.Web.UI.Page { }
    // in file UserPage.aspx

    or

    b)

    public class User : System.Web.UI.Page { }
    // in file User.aspx


    Thanks, Marco