Krzysztof Cwalina Program Manager Microsoft Corporation Brad Abrams Product Unit Manager.

82
Framework Design Guidelines Krzysztof Cwalina Program Manager Microsoft Corporation http://blogs.msdn.com/k cwalina Brad Abrams Product Unit Manager Microsoft Corporation http://blogs.msdn.com/b rada PC58

Transcript of Krzysztof Cwalina Program Manager Microsoft Corporation Brad Abrams Product Unit Manager.

Page 1: Krzysztof Cwalina Program Manager Microsoft Corporation    Brad Abrams Product Unit Manager.

Framework Design Guidelines

Krzysztof CwalinaProgram ManagerMicrosoft Corporationhttp://blogs.msdn.com/kcwalina

Brad AbramsProduct Unit ManagerMicrosoft Corporationhttp://blogs.msdn.com/brada

PC58

Page 2: Krzysztof Cwalina Program Manager Microsoft Corporation    Brad Abrams Product Unit Manager.
Page 3: Krzysztof Cwalina Program Manager Microsoft Corporation    Brad Abrams Product Unit Manager.

It has been 10 years since we started the Design Guidelines effort….

1998

Dow Jones Industrial Average

@ 9,000

Page 5: Krzysztof Cwalina Program Manager Microsoft Corporation    Brad Abrams Product Unit Manager.

Member Design

Page 6: Krzysztof Cwalina Program Manager Microsoft Corporation    Brad Abrams Product Unit Manager.

In 1998, the crew of the Voyager found themselves 75,000 light years from earth and had to learn the new ways of communicating in the Delta Quadrant

In 1998, the crew of the .NET Framework found themselves 75,000 light years behind Java and had to define a new way of communicating with developers

Page 7: Krzysztof Cwalina Program Manager Microsoft Corporation    Brad Abrams Product Unit Manager.

Communicate via leaving artifacts

Framework Design Artifacts:• Properties• Methods • Events• Constructors

Page 8: Krzysztof Cwalina Program Manager Microsoft Corporation    Brad Abrams Product Unit Manager.

8

Constructors are

Do minimal work in the constructor Be Lazy! Only capture the parameters

public class XmlFile { string filename; Stream data; public XmlFile(string filename) { this.data = DownloadData(filename); }}

public XmlFile(string filename) { this.filename = filename; }

lazy

Page 9: Krzysztof Cwalina Program Manager Microsoft Corporation    Brad Abrams Product Unit Manager.

Properties

Property getters should be simple and therefore unlikely to throw exceptions

Properties should not have dependencies on each other Setting one property should not affect other

properties Properties should be settable in any order

public class ArrayList { public int Count {get;}}

Page 10: Krzysztof Cwalina Program Manager Microsoft Corporation    Brad Abrams Product Unit Manager.

Properties versus Methods

Use a Property: If the member logical attribute of the type

Use a method: If the operation is a conversion,

such as ToString() If the getter has an observable

side effect If order of execution is important If the method might not return

immediately If the member returns an array

Page 11: Krzysztof Cwalina Program Manager Microsoft Corporation    Brad Abrams Product Unit Manager.

EmployeeList l = FillList();for (int i = 0; i < l.Length; i++){ if (l.All[i] == x){...}}

if (l.GetAll()[i]== x) {...}

public Employee[] All {get{}}

public Employee[] GetAll() {}

Moral: Use method if the operation is expensive

Calling Code

Properties and returning arrays

Page 12: Krzysztof Cwalina Program Manager Microsoft Corporation    Brad Abrams Product Unit Manager.

In 2008, the best Star Trek engineers developed new construction techniques to build the first starship Enterprise.

In 2008, the best Microsoft engineers developed new construction techniques to build software for the enterprise.

Page 13: Krzysztof Cwalina Program Manager Microsoft Corporation    Brad Abrams Product Unit Manager.

Extension Methods

namespace MyCompany.StringManipulation {

public static class StringExtensions{

public static bool IsNullOrEmpty(this string s){ return String.IsNullOrEmpty(s);

}

}

}

using MyCompany.StringManipulation;

string message= “hello world”;

if(message.IsNullOrEmpty()){

Console.WriteLine(“EMPTY”);

}

Page 14: Krzysztof Cwalina Program Manager Microsoft Corporation    Brad Abrams Product Unit Manager.

Extension methods marry the usability offered by object-oriented APIs with the flexibility of functional APIs.

Page 15: Krzysztof Cwalina Program Manager Microsoft Corporation    Brad Abrams Product Unit Manager.

CONSIDER using extension methods to "add" methods to interfacespublic interface IFoo{ void Bar(string x, bool y); void Bar(string x);}public static class IFooExtensions{ public static void Bar(this IFoo foo, string x){ foo.Bar(x,false); }}

…IFoo foo = …;foo.Bar(“Hi!”);

Page 16: Krzysztof Cwalina Program Manager Microsoft Corporation    Brad Abrams Product Unit Manager.

CONSIDER using extension methods to manage dependencies

Uri uri = “ftp://some.ftp.uri”.ToUri();

// higher level assembly (not mscorlib)

namespace System.Net {

public static class StringExtensions{

public static Uri ToUri(this string s){ … }

}

}

Page 17: Krzysztof Cwalina Program Manager Microsoft Corporation    Brad Abrams Product Unit Manager.

AVOID frivolously defining extension methods, especially on types you don’t own Might add clutter Choose namespaces for sponsor types carefully Remember that not all languages support

extension methods Users will have to use static method call syntax

Page 18: Krzysztof Cwalina Program Manager Microsoft Corporation    Brad Abrams Product Unit Manager.

AVOID defining extension methods on System.Object

// C# declaration of the extension methodpublic static class SomeExtensions{ static void SomeMethod(this object o){…}} ‘ VB will try to find the method at runtime‘ … but extension methods are resolved at‘ compile time.Dim o As Object = …o.SomeMethod() ‘ THIS WILL THROW

‘ VB users will have to call the method using the regular static method call syntax.SomeExtensions.SomeMethod(o)

Page 19: Krzysztof Cwalina Program Manager Microsoft Corporation    Brad Abrams Product Unit Manager.

Type Design

Page 20: Krzysztof Cwalina Program Manager Microsoft Corporation    Brad Abrams Product Unit Manager.

Around 1998, Bourne starts with only a 10-digit account number on a quest to find out who he is and who he is not

Around 1998, we start with a 10-page design guidelines document on a quest to find out how we should design frameworks and how we should not

Page 21: Krzysztof Cwalina Program Manager Microsoft Corporation    Brad Abrams Product Unit Manager.

Framework Design Theater

The Main Character: Bright young developer

The Setting: Her first big project

The Setup: Create a class that models a car

Actions required: Start and Drive

Page 22: Krzysztof Cwalina Program Manager Microsoft Corporation    Brad Abrams Product Unit Manager.

Design Pass One: Meets Requirements

Pass one: meets requirements

Page 23: Krzysztof Cwalina Program Manager Microsoft Corporation    Brad Abrams Product Unit Manager.

Design Pass Two: More than Enough

Page 24: Krzysztof Cwalina Program Manager Microsoft Corporation    Brad Abrams Product Unit Manager.

24

Design Pass Three: Way too much

Page 25: Krzysztof Cwalina Program Manager Microsoft Corporation    Brad Abrams Product Unit Manager.

Time to Ship…

Time to cut…

Page 26: Krzysztof Cwalina Program Manager Microsoft Corporation    Brad Abrams Product Unit Manager.

26

What we ship: Too much and not enough…

Page 27: Krzysztof Cwalina Program Manager Microsoft Corporation    Brad Abrams Product Unit Manager.

V.Next: Worse Yet

Now we want to add Color and Model, and we know exactly how

But it is much harder because the design is half done and mostly wrong

Page 28: Krzysztof Cwalina Program Manager Microsoft Corporation    Brad Abrams Product Unit Manager.

The moral

Do as little as possible now (but no less) to ensure room for extensibility in the future

Page 29: Krzysztof Cwalina Program Manager Microsoft Corporation    Brad Abrams Product Unit Manager.

Abstract and Base classes

Prefer broad, shallow hierarchies Less than or equal to 2 additional levels – Rough

rule! Contracts and responsibilities are difficult to

maintain and explain in deep complex hierarchies

Consider making base classes not constructible (that is, use abstract classes) Make it clear what the class is for Provide a protected constructor for subclasses to

call System.Exception should not have had a public

constructor

Page 30: Krzysztof Cwalina Program Manager Microsoft Corporation    Brad Abrams Product Unit Manager.

Virtual Method Example

public class TheBase : Object {

public override string ToString() {

return “Hello from the Base";

}

}public class Derived : TheBase {

public override string ToString() {

return “Hello from Derived";

}

}

Page 31: Krzysztof Cwalina Program Manager Microsoft Corporation    Brad Abrams Product Unit Manager.

Virtual Methods

What is printed out?

Derived d = new Derived();Console.WriteLine (d.ToString());

TheBase tb = d;Console.WriteLine (tb.ToString());

Object o = tb;Console.WriteLine (o.ToString());

Page 32: Krzysztof Cwalina Program Manager Microsoft Corporation    Brad Abrams Product Unit Manager.

Virtual Methods

They all output “Hello from Derived”. Why? Method call virtualizes at runtime The static type doesn’t matter

This is the danger and power of virtual methods Danger: Owner of base classes cannot control what

subclasses do Power: Base class does not have to change as new

subclasses are created

Page 33: Krzysztof Cwalina Program Manager Microsoft Corporation    Brad Abrams Product Unit Manager.

Overriding: Follow the Contract

Don’t change the semantics of member Follow the contract

defined on the base class

All Virtual members should define a contractDon’t require clients to have knowledge of your overridingShould you call the base?

Page 34: Krzysztof Cwalina Program Manager Microsoft Corporation    Brad Abrams Product Unit Manager.

Virtual and non-virtual

Use non-virtual members unless you have specifically designed for specialization Have a concrete scenario in mind Write the code!

Follow the Liskov Substitution Principle References to base types must

work with derived types without knowing the difference Must continue to call in the same

order and frequency Cannot increase or decrease range of inputs or

output

Barbara Liskov

Page 35: Krzysztof Cwalina Program Manager Microsoft Corporation    Brad Abrams Product Unit Manager.

Interface Usage

No common implementation (the ActiveX problem)

Challenging to version over releases The smaller, more focused the interface the

better 1-2 members are best But interfaces can be defined in terms of other

simpler interfaces

public interface IComparable { int CompareTo(object obj);}

Page 36: Krzysztof Cwalina Program Manager Microsoft Corporation    Brad Abrams Product Unit Manager.

The great proof of madness is the disproportion of one's designs to

one's means. Napoleon Bonaparte

Page 37: Krzysztof Cwalina Program Manager Microsoft Corporation    Brad Abrams Product Unit Manager.

Around 2008, Bourne kills 436 people while (still) on a quest to find out who he is and who he is not

Around 2008, we publish a 436 page book (still) on a quest to find out how we should design frameworks and how we should not

Page 38: Krzysztof Cwalina Program Manager Microsoft Corporation    Brad Abrams Product Unit Manager.

Type Dependency Management

Careful dependency management is the necessary ingredient to successful evolution of frameworks. Without it, frameworks quickly deteriorate and are forced out of relevance prematurely.

Page 39: Krzysztof Cwalina Program Manager Microsoft Corporation    Brad Abrams Product Unit Manager.

Framework Layering

Page 40: Krzysztof Cwalina Program Manager Microsoft Corporation    Brad Abrams Product Unit Manager.

DO NOT have upward dependencies

BCL

WPF XML

Reflection

AVOID horizontal dependencies

Page 41: Krzysztof Cwalina Program Manager Microsoft Corporation    Brad Abrams Product Unit Manager.

Libraries , Primitives, Abstractions

Page 42: Krzysztof Cwalina Program Manager Microsoft Corporation    Brad Abrams Product Unit Manager.

CONSIDER placing library types higher on the dependency stack Definition:

Library types are types that are not passed between components

Examples EventLog, Debug,

Easy to Evolve Leave old in, add new one Beware of duplication!

Page 43: Krzysztof Cwalina Program Manager Microsoft Corporation    Brad Abrams Product Unit Manager.

DO keep primitives policy free (i.e. simple)

Definition: Primitive types are types that are passed between

components and have very restricted extensibility (i.e. no subtype can override any members)

Examples Int32, String, Uri.

Hard to Evolve Little need to Evolve Typically in lower layers

Page 44: Krzysztof Cwalina Program Manager Microsoft Corporation    Brad Abrams Product Unit Manager.

DO NOT create abstractions unless you know what you are doing Definition:

Abstractions are interfaces or classes with unsealed members that are passed between components.

Examples Stream, IComponent

Hard to Evolve Unfortunately, pressure to evolve

Page 45: Krzysztof Cwalina Program Manager Microsoft Corporation    Brad Abrams Product Unit Manager.

Trends

Page 46: Krzysztof Cwalina Program Manager Microsoft Corporation    Brad Abrams Product Unit Manager.

Around 1998, Indian Jones must face several tests to find the holy grail and save his father

Around 1998, Microsoft must face several tests to find the holy grail of productivity and save the developers.

Page 47: Krzysztof Cwalina Program Manager Microsoft Corporation    Brad Abrams Product Unit Manager.

The Secret of Achiving Great

Productivty A Pit!!

Page 48: Krzysztof Cwalina Program Manager Microsoft Corporation    Brad Abrams Product Unit Manager.

The Pit of Success: in stark contrast to a summit, a peak, or a

journey across a desert to find victory through many trials and

surprises, we want our customers to simply fall into winning practices

by using our platform and frameworks. To the extent that we make it easy to get into trouble we

fail.- Rico Mariani

Page 49: Krzysztof Cwalina Program Manager Microsoft Corporation    Brad Abrams Product Unit Manager.

49

Is using your framework correctly like…

Climbing a mountain?

Page 50: Krzysztof Cwalina Program Manager Microsoft Corporation    Brad Abrams Product Unit Manager.

50

Is using your framework correctly like…

Scaling a peak?

Page 51: Krzysztof Cwalina Program Manager Microsoft Corporation    Brad Abrams Product Unit Manager.

51

Is using your framework correctly like…

Running across a desert?

Page 52: Krzysztof Cwalina Program Manager Microsoft Corporation    Brad Abrams Product Unit Manager.

Is using your framework correctly like…

Falling into a pit?

Page 53: Krzysztof Cwalina Program Manager Microsoft Corporation    Brad Abrams Product Unit Manager.

Make using your framework as easy as falling into a pit –

then you have achived great productivity

Page 54: Krzysztof Cwalina Program Manager Microsoft Corporation    Brad Abrams Product Unit Manager.

Around 2008, Indiana uncovers the secret behind mysterious artifacts known as the Crystal Skulls

Around 2008, we uncover the secret behind mysteriously well designed code known as “testing”

Page 55: Krzysztof Cwalina Program Manager Microsoft Corporation    Brad Abrams Product Unit Manager.

Test Driven Development

Write tests first, design later Requires reusable APIs to be testable:

Avoid heavy dependencies, consider inversion of control.

Consider designing for dependency injection.

Page 56: Krzysztof Cwalina Program Manager Microsoft Corporation    Brad Abrams Product Unit Manager.

Heavy Dependencies and Testability

// your API

public class Tracer {

MessageQueue mq = new MessageQueue(…);

public void Trace(string message){ mq.Send(message);

}

}

// your customer’s program that is hard to test

Tracer tracer = new Tracer();

public void ProcessOrder(Order order){

tracer.Trace(order.Id);

}

Page 57: Krzysztof Cwalina Program Manager Microsoft Corporation    Brad Abrams Product Unit Manager.

Inversion of Control

// your better API

public abstract class TraceListener {

public abstract void Trace(string message);

}

public class Tracer {

TraceListener listener;

public Tracer(TraceListener listener){

this.listener = listener;

}

public void Trace(string message){

listener.Trace(message);

}

}

Page 58: Krzysztof Cwalina Program Manager Microsoft Corporation    Brad Abrams Product Unit Manager.

Dependency Injection

// your customer’s program that is easier to test

Tracer tracer = new Tracer(new FileListener());

public void ProcessOrder(Order order){

tracer.Trace(order.Id);

}

Page 59: Krzysztof Cwalina Program Manager Microsoft Corporation    Brad Abrams Product Unit Manager.

Dependency Injection Containers

// customer’s program that is even easier to test

Tracer tracer = container.Resolve<Tracer>();

public void ProcessOrder(Order order){

tracer.Trace(order.Id);

}

Check out DI Containers (a.k.a. IoC Containers): autofac, Castle Windsor, PicoContainer.NET, Spring.NET, StructureMap, Unity, and others.

Page 60: Krzysztof Cwalina Program Manager Microsoft Corporation    Brad Abrams Product Unit Manager.

Tools

Page 61: Krzysztof Cwalina Program Manager Microsoft Corporation    Brad Abrams Product Unit Manager.

Even before 1998, a lone crime fighter battles the forces of evil with the help of an artificially intelligent supercar: KITT

Even before 1998, we battle evil underscores with the help of an artificially intelligent supertool: FxCop

Page 62: Krzysztof Cwalina Program Manager Microsoft Corporation    Brad Abrams Product Unit Manager.

When you pick up your rental car….

Push the seat all the way back Find an NPR station Find the exit

Read the manual??

Page 63: Krzysztof Cwalina Program Manager Microsoft Corporation    Brad Abrams Product Unit Manager.

Oh, down to lock…

Page 64: Krzysztof Cwalina Program Manager Microsoft Corporation    Brad Abrams Product Unit Manager.

How to use a key…

Page 65: Krzysztof Cwalina Program Manager Microsoft Corporation    Brad Abrams Product Unit Manager.

Oh, you push the PRESS button…

Page 66: Krzysztof Cwalina Program Manager Microsoft Corporation    Brad Abrams Product Unit Manager.

Who actually needs this data?

Page 67: Krzysztof Cwalina Program Manager Microsoft Corporation    Brad Abrams Product Unit Manager.

Why you don’t read rental car manuals ???

You know how to drive your car All cars work basically the same way Your rental car is a car Therefore, you can drive your rental car

That is…

Page 68: Krzysztof Cwalina Program Manager Microsoft Corporation    Brad Abrams Product Unit Manager.

Naming Conventions

PascalCasing – Each word starts with an uppercase letter

camelCasing – First word lower case, others uppercase

SCREAMING_CAPS – All upper case with underscores

Page 69: Krzysztof Cwalina Program Manager Microsoft Corporation    Brad Abrams Product Unit Manager.

Naming Conventions

All types and publicly exposed members are PascalCased

Parameters are camelCased

public class MemberDoc{ public int CompareTo(object value) public string Name { get;}}

Page 70: Krzysztof Cwalina Program Manager Microsoft Corporation    Brad Abrams Product Unit Manager.

Hungarian Notation

Do not use Hungarian notation in publicly exposed APIs and parameter names

public class CMyClass { int CompareTo (object objValue) {..} string lpstrName {get;} int iValue {get;}}

Page 71: Krzysztof Cwalina Program Manager Microsoft Corporation    Brad Abrams Product Unit Manager.

On Abbreviations, acronym, initialism and the like…

Avoid them! They are a classic JLT (jargon loaded term) OK to use them once they become words

Html, Xaml, etc Don’t just spell them out

Use a meaningful name Abbreviations of more than 2 letters are cased

as words, otherwise ALLUPPER IO vs. Html

Page 72: Krzysztof Cwalina Program Manager Microsoft Corporation    Brad Abrams Product Unit Manager.

While we are on naming…

Good naming is hard—it takes time Be meaningful but brief

Use US-English Colour vs. Color

Principle of least surprise Look for prior-art

NumberOfElements vs. Count

Page 73: Krzysztof Cwalina Program Manager Microsoft Corporation    Brad Abrams Product Unit Manager.

FxCop – Keeping the "power of sameness"http://blogs.msdn.com/fxcop

Page 74: Krzysztof Cwalina Program Manager Microsoft Corporation    Brad Abrams Product Unit Manager.

Around 2008, our hero gets 550 horsepower solar hybrid engine, biomedical scanner, and military satellite access

Around 2008, framework designer heroes get dependency analysis engine, and API diff scanner.

Page 75: Krzysztof Cwalina Program Manager Microsoft Corporation    Brad Abrams Product Unit Manager.

Framework Design Studiohttp://code.msdn.microsoft.com/fds

Page 76: Krzysztof Cwalina Program Manager Microsoft Corporation    Brad Abrams Product Unit Manager.

Dependency Management Toolshttp://code.msdn.microsoft.com/fxarch Define Components

<Group ID=“Component1”><Bin Name=“MyCompany.FeatureA.dll”/><Bin Name=“MyCompany.FeatureB.dll”/>

</Group>

Define Rules <Allow From=“Component1" To=“WPF"/><Deny To=“XMLDOM”>

Run and Get Output:From group Component1: MyCompany.FeatureA.dll should not depend on:

SomeOtherComponent SomeOtherComponent.dll

Also check out NDepend – a tool for visualizing dependencies.

Page 77: Krzysztof Cwalina Program Manager Microsoft Corporation    Brad Abrams Product Unit Manager.

Summary

10 years of Framework design.. Core Principles of Framework design have

stayed the same There are some significant new advances

Check out the new book!

Brad Abramshttp://blogs.msdn.com/brada

Krzysztof Cwalinahttp://blogs.msdn.com/kcwalina

Please fill out the session evals!

Page 78: Krzysztof Cwalina Program Manager Microsoft Corporation    Brad Abrams Product Unit Manager.

Some images of movie posters sourced from www.imdb.com

Page 79: Krzysztof Cwalina Program Manager Microsoft Corporation    Brad Abrams Product Unit Manager.

Evals & Recordings

Please fill

out your

evaluation for

this session at:

This session will be available as a recording at:

www.microsoftpdc.com

Page 80: Krzysztof Cwalina Program Manager Microsoft Corporation    Brad Abrams Product Unit Manager.

Please use the microphones provided

Q&A

Page 81: Krzysztof Cwalina Program Manager Microsoft Corporation    Brad Abrams Product Unit Manager.

© 2008 Microsoft Corporation. All rights reserved. Microsoft, Windows, Windows Vista and other product names are or may be registered trademarks and/or trademarks in the U.S. and/or other countries.The information herein is for informational purposes only and represents the current view of Microsoft Corporation as of the date of this presentation. Because Microsoft must respond to changing market

conditions, it should not be interpreted to be a commitment on the part of Microsoft, and Microsoft cannot guarantee the accuracy of any information provided after the date of this presentation. MICROSOFT MAKES NO WARRANTIES, EXPRESS, IMPLIED OR STATUTORY, AS TO THE INFORMATION IN THIS PRESENTATION.

Page 82: Krzysztof Cwalina Program Manager Microsoft Corporation    Brad Abrams Product Unit Manager.