.NET开发

本类阅读TOP10

·NHibernate快速指南(翻译)
·vs.net 2005中文版下载地址收藏
·【小技巧】一个判断session是否过期的小技巧
·VB/ASP 调用 SQL Server 的存储过程
·?dos下编译.net程序找不到csc.exe文件
·通过Web Services上传和下载文件
·学习笔记(补)《.NET框架程序设计(修订版)》--目录
·VB.NET实现DirectDraw9 (2) 动画
·VB.NET实现DirectDraw9 (1) 托管的DDraw
·建站框架规范书之——文件命名

分类导航
VC语言Delphi
VB语言ASP
PerlJava
Script数据库
其他语言游戏开发
文件格式网站制作
软件工程.NET开发
On Designing Good Libraries -- Part II

作者:未知 来源:月光软件站 加入时间:2005-2-28 月光软件站

Brad Abrams

 

You asked for it, you got it.. feedback always welcome.

 

 

 

Attribute Usage

?FONT face="Times New Roman" size=1>         Suffix with 揂ttribute?O:P>

?FONT face="Times New Roman" size=1>         Perf tip: seal attribute classes for faster runtime lookup

?FONT face="Times New Roman" size=1>         Specify the AttributeUsage attribute completely

?FONT face="Times New Roman" size=1>         Don抰 rely on the defaults!

?FONT face="Times New Roman" size=1>         Be as restrictive as possible

?FONT face="Times New Roman" size=1>         You can always open it up later

[AttributeUsage(
      AttributeTargets.All,
      Inherited = true,
      AllowMultiple = false)]

 

?FONT face="Times New Roman" size=1>         AttributeTargets ?where is the attribute allowed to be applied?

?FONT face="Times New Roman" size=1>         Inherited ?should derived members/types be considered to have this attribute?

?FONT face="Times New Roman" size=1>         AllowMultiple ?Is it legal to put more than one instance of the attribute on a particular member?

 

?FONT face="Times New Roman" size=1>         Use constructor arguments for required parameters (positional arguments)

?FONT face="Times New Roman" size=1>         Provide a read-only property with the same name

?FONT face="Times New Roman" size=1>         Use read-write properties for optional parameters (named arguments)

?FONT face="Times New Roman" size=1>         Never use overloaded constructors

[AttributeUsage(AttributeTargets.All, AllowMultiple=true,
                   Inherited=false)]
public class NameAttribute : Attribute {
   public NameAttribute (string userName) {..}
   public string UserName {get {..}}
   public int Age {get {..} set{..}}
} //end class

 

Usage:

[NameAttribute("Bob", Age=87)]

 

UserName ?positional argument

Age ?named argument

 

Static Classes

?FONT face="Times New Roman" size=1>         Static classes contain just static members

?FONT face="Times New Roman" size=1>         Compromise between pure OO design with usability

?FONT face="Times New Roman" size=1>         Commonly used for

?FONT face="Times New Roman" size=1>         Shortcuts for other operations (System.IO.File)

?FONT face="Times New Roman" size=1>         Functionality for which a full OO wrapper is unwarranted (System.Environment)

 

public sealed class Environment  {

  private Environment(){} //prevents creation

  public static void Exit(int exitCode) {..}

  public static int ExitCode {

    get {..}

    set {..}

  }

  public static string CommandLine {

    get {..}

  }

}

 

?FONT face="Times New Roman" size=1>         Best used when:

?FONT face="Times New Roman" size=1>         Clear charter for the class

?FONT face="Times New Roman" size=1>         Not a 搈iscellaneous?bucket

?FONT face="Times New Roman" size=1>         Not the center point of a design

?FONT face="Times New Roman" size=1>         Use sparingly

?FONT face="Times New Roman" size=1>         Watch out for disconnected design

?FONT face="Times New Roman" size=1>         Static classes

?FONT face="Times New Roman" size=1>         Are sealed

?FONT face="Times New Roman" size=1>         Have private default constructor

?FONT face="Times New Roman" size=1>         No instance members

?FONT face="Times New Roman" size=1>         Static Classes: Bad Design

?FONT face="Times New Roman" size=1>         Late in the final milestone we added a method to tell if the runtime is being shut down

?FONT face="Times New Roman" size=1>         However we added the method as an instance method making it completely uncallable

?FONT face="Times New Roman" size=1>         public sealed class Environment {
   private Environment() {} //Prevent creation
   // ---snip---
   public bool HasShutdownStarted {
      get { return nativeHasShutdown(); }
   }
   public static string UserName { get {...} }
   private static extern bool nativeHasShutdown();
   // ---snip---
}

?FONT face="Times New Roman" size=1>          

 

Constructors

?FONT face="Times New Roman" size=1>         Do minimal work in the constructor

?FONT face="Times New Roman" size=1>         Only capture the parameters

?FONT face="Times New Roman" size=1>         Cost is delayed

?FONT face="Times New Roman" size=1>         You can throw exceptions from constructors

?FONT face="Times New Roman" size=1>         Be consistent in the ordering and naming of constructor parameters

 

public class Foo  {
   private const string defaultA = "..";
   private const string defaultB = "..";
   public Foo():
      this(defaultA,defaultB) {}
   public Foo(string a):
      this(a, defaultB) {}
   public Foo(string a, string b) {
       /* do work here */
   }
}

 

?FONT face="Times New Roman" size=1>         Many languages automatically add a public default constructor if you don抰 specify any

?FONT face="Times New Roman" size=1>         Abstract classes get a protected constructor

?FONT face="Times New Roman" size=1>         These two code snippets are equivalent:

public class Foo {

}

public class Foo {

   public Foo () {}

}

 

?FONT face="Times New Roman" size=1>         Always explicitly add a default constructor to avoid versioning issues

?FONT face="Times New Roman" size=1>         Adding a new constructor removes the default one, breaking clients

// V1

public class Foo {

}

Calling Code works: Foo f = new Foo()

 

// V2

public class Foo {
  public Foo (int value)

}

Calling code breaks: Foo f = new Foo()

 

Method Usage

 

?FONT face="Times New Roman" size=1>         Use overloading only when the overloads do semantically the same thing

?FONT face="Times New Roman" size=1>         Incorrect overload:

String.IndexOf(string value) {}

String.IndexOf(char[] anyOf) {}

 

?FONT face="Times New Roman" size=1>         Correct overload:

Convert.ToString(int value) {}

Convert.ToString(double value) {}

 

?FONT face="Times New Roman" size=1>         Used to avoid boxing

?FONT face="Times New Roman" size=1>        Write(object) works for any type

?FONT face="Times New Roman" size=1>        But specialization avoids boxing

?FONT face="Times New Roman" size=1>        Do only when completely special casing

public static void Write (bool value);
public static void Write (int value);
public static void Write (double value);
public static void Write (object value);

 

?FONT face="Times New Roman" size=1>         Use appropriate default values

?FONT face="Times New Roman" size=1>         Simple method assumes default state

?FONT face="Times New Roman" size=1>         More complex methods indicate changes from the default state

MethodInfo Type.GetMethod (string name);
    //ignoreCase = false

MethodInfo Type.GetMethod (string name,
    boolean ignoreCase);

?FONT face="Times New Roman" size=1>         Use a zeroed state for the default value (such as: 0, 0.0, false, 摂, etc.)

?FONT face="Times New Roman" size=1>         Be consistent in the ordering and naming of method parameters

?FONT face="Times New Roman" size=1>         Only the method with the most parameters should be virtual if needed

public class Foo {
   private const string defaultForA = "a default";
   private const int defaultForB = 42;
   public void Bar(){
      Bar(defaultForA, defaultForB);
   }
   public void Bar (string a){
      Bar(a, defaultForB);
   }
   public /*virtual*/ void Bar (string a, int b){
      // core implementation here
   }
}

 

?FONT face="Times New Roman" size=1>         Variable number of arguments (e.g. printf)

?FONT face="Times New Roman" size=1>         Use params

public static string Format(string format,

     params object[] args);

 

?FONT face="Times New Roman" size=1>         Not used for in/out params (e.g. scanf)

?FONT face="Times New Roman" size=1>         Only provide overloads for performance reasons IF you special case each code path

 

void Format (string formatString, object arg1)

void Format (string formatString, object arg1, object arg2)

void Format (string formatString, params object [] args)

 

 

?FONT face="Times New Roman" size=1>         Allowing method inlining by the JIT

?FONT face="Times New Roman" size=1>         Minimize the use of virtual methods

?FONT face="Times New Roman" size=1>         Don抰 write really large methods

?FONT face="Times New Roman" size=1>         Don抰 have large numbers of locals

More to come...




相关文章

相关软件