the art of building a reusable class library n.
Skip this Video
Loading SlideShow in 5 Seconds..
The Art of Building a Reusable Class Library PowerPoint Presentation
Download Presentation
The Art of Building a Reusable Class Library

The Art of Building a Reusable Class Library

121 Vues Download Presentation
Télécharger la présentation

The Art of Building a Reusable Class Library

- - - - - - - - - - - - - - - - - - - - - - - - - - - E N D - - - - - - - - - - - - - - - - - - - - - - - - - - -
Presentation Transcript

  1. The Art of Building a Reusable Class Library Brad Abrams – BradA@Microsoft.comKrzysztof Cwalina - Microsoft Corporation

  2. Turn frustrated developers … into happy developers

  3. Goals • Understand that API design matters • Recognize good API design • Lots of good and bad examples • Learn the API design process

  4. Who is this precon for? 1. Developers building reusable library or component 2. Developer building apps to explicitly understand the rules of the .NET Framework and WinFX

  5. Being complex is easy, being simple is hard Quote of the day I have yet to see any problem, however complicated, which, when looked at the right way did not become still more complicated. Poul Anderson

  6. Project Cost Model Source: Gartner, May 2002: “The Cost and Risk of Application Development Decisions”Joseph Feiman, Tom Berg

  7. Four Keys of Framework Design • Tools for Communication The Power of Sameness Framework Design Matters The Pit of Success

  8. The Power of Sameness Brad Abrams

  9. Read the manual?? When you pick up your rental car…. • Push the seat all the way back • Find an NPR station • Find the exit

  10. Oh, down to lock…

  11. How to use a key…

  12. Oh, you push the PRESS button…

  13. Who actually needs this data?

  14. 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… The Power of Sameness

  15. New System Producers and Sameness Market Potential Standard System

  16. Are things equally as obvious in your framework designs? Maybe you are missing…. The Power of Sameness

  17. Naming Conventions PascalCasing – Each word starts with an uppercase letter camelCasing – First word lower case, others uppercase SCREAMING_CAPS – All upper case with underscores

  18. “Blink” Quiz I class1MyClass; Blink : The Power of Thinking Without Thinking

  19. “Blink” Quiz I • At-a-glance, first impressions… what does this likely do? • A: Compiler error • B: Class declaration • C: Variable declaration • D: Other class1MyClass; Change the casing to match the pattern, is it easier to tell what this is? Class1myClass;

  20. 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;} } Section 4.1, “Naming Conventions”

  21. 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;} }

  22. Hungarian Notation (continued) • The prefix codes are arbitrary and difficult to learn • They make it harder to read an identifier name • Hungarian was developed for a time when languages were loosely typed and IDEs were not as powerful • E.g. “out” and “ref” parameters information now conveyed at the call site. Interlocked.Increment(ref i)

  23. 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

  24. 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

  25. “Blink” Quiz II • Does this compile? IFoo foo = new IFoo(); • “No” because you can’t create instances of interfaces • Why do we assume IFoo is an interface? The Power of Sameness

  26. Section 4.1, “Naming Conventions” Suffixes and Prefixes • Interfaces prefix with “I” • A tribute to COM • Exceptions and Attributes suffixed public interface IFormattable {} Public class NameAttribute : Attribute {} Public class PrinterOnFireException: Exception {}

  27. Section 7.3.4, “ArgumentNullException” Quick Quiz • What is wrong this this type? public class ArgumentNullException : ArgumentException { public ArgumentNullException () {} public ArgumentNullException (string paramName) {} public ArgumentNullException (string paramName, string message) {}}

  28. Common Exception Usage throw new IOException(); • Developers expect all exceptions to work this way… • Make your exception meet expectations… throw new FormatException(); throw new ArgumentException(); throw new InvalidOperationException();

  29. Section 7.4, “Designing Custom Exceptions” Exception Constructor Pattern • Every exception should have at least the top three constructors public class XxxException : YyyException { public XxxException () {} public XxxException (string message) {} public XxxException (string message, Exception inner) {} protected XxxException ( SerializationInfo info, StreamingContext context) {}}

  30. Section 7.3.4, “ArgumentNullException” Remember this type…. • What is wrong this this type? public class ArgumentNullException : ArgumentException { public ArgumentNullException () {} public ArgumentNullException (string paramName) {} public ArgumentNullException (string paramName, string message) {}}

  31. You are optimizing locally, you are making the right decision if developers only use your type, but if they use others as well…. API design theater… I see… why not? 90% of the time the message is not used, the param name is what is important It doesn’t apply in this case Why didn’t you follow the exception pattern? The Architect The Developer

  32. Missing the power of sameness • Result: Habit wins out and people commonly type: throw new ArgumentNullException ("the value must pass an employee name"); • We end up with odd error messages such as: Unhandled Exception: System.ArgumentNullException: Value cannot be null.Parameter name: the value must pass an employee name • Moral: Just follow the pattern! throw new ArgumentNullException ("Name", "the value must pass an employee name");

  33. Method Overloading:Abusing the Power of Sameness • Overloaded: Method on the same type with the same name, but different number or type of arguments public static string ToString(int value) {} public static stringToString(double value) {}

  34. Bertrand Meyer Dangers of Method Overloading • Meyer: A single operation should do a single thing.. Why does this man dislike method overloading? Abrams: Good method overloading is a single thing – all overloads are semantically the same

  35. Section 5.1.1, “Method Overloading” Method Overloading String.IndexOf(string value) {} String.IndexOf(char[] anyOf) {} string s = "brad abrams";s.IndexOf("ab"); // == 5s.IndexOf('ab'); // == 0 Cobol actually does allow syntax like this Moral: Don’t overload when the methods are semantically different

  36. Section 5.1.1, “Method Overloading” Method Overloading • Use overloading only when the overloads do semantically the same thing • Incorrect overload: • Correct overload: String.IndexOf(string value) {} String.IndexOf(char[] anyOf) {} Convert.ToString(int value) {} Convert.ToString(double value) {}

  37. Section 5.1.1, “Method Overloading” Method Overloading: Defaults • Use appropriate default values • Simple method assumes default state • More complex methods indicate changes from the default state • Use a zeroed state for the default value (such as: 0, 0.0, false, null, etc.) MethodInfo Type.GetMethod (string name); //ignoreCase = false MethodInfo Type.GetMethod (string name, boolean ignoreCase);

  38. Section 5.3, “Constructor Design” Constructors and Properties • Constructor’s parameters are shortcuts for setting properties • No difference in semantics between these code snippets EventLog log = new EventLog();log.MachineName = “kcwalina0”;log.Log = “Security”; EventLog log = new EventLog(“Security”);log.MachineName = “kcwalina0”; EventLog log = new EventLog(“Security”,”kcwalina0”);

  39. Exercises…

  40. Exercise: Code Review public class HtmlEncoding { public const string DEFAULT_NAME = "Html3.2"; public HtmlEncoding (int iCount) {..} public string Tagname {get {..}} public bool UseIoCompletionPort {get {..}} protected void _coreSetValue (double value) {..} private IntPtr ptrValue; }

  41. Exercise: Naming Conventions What are good reasons to violate naming conventions? • “I used to work in [C++, Java, COBOL]” • “Our previous version used SCREAMING_CAP” • “These are initials from someone’s name, they have to be all upper case”

  42. Exercise: Code Review public interface Convertible {} Public class CodeReviewer : Attribute {} Public class InputInvalidError: Exception {}

  43. Exercise: Code Review public static int MaxValue = 9999999; public void Withdraw () { Withdraw (MaxValue)} public void Withdraw (int amount) { …}

  44. Summary • The Power of Sameness Teaches us • Influence of expectations Naming conventions and common suffixes\prefixes • Habits win out over the special cases Common Exception pattern • With great power comes great responsibility Method overloading • Meet developers where they are constructors and properties pattern teaches us to meet developers’ expectations

  45. Questions?

  46. Framework Design Matters The role of a framework designer in the development process Krzysztof Cwalina Microsoft

  47. The process of framework design is very different from prototyping and implementation

  48. Developers focus on a different level

  49. Similarly to implementations framework design must be … • Simple • Integrated • Consistent • Evolvable ... but the similarities are superficial

  50. Well-designed framework must be simple