The Elements of C# Style - Design

15563 단어 element
1. 공사
1.1 공사를 두려워하지 마라
모든 이론적으로 가능한 과학적 실현을 코드로 모델링하려 하지 마라.제한적인 코드로 쓴 것은 결코 잘못이 아니다. 이러한 제한성이 제품 시리즈의 기능에 영향을 미치지 않을 것이라고 확신하기만 하면.
1.2 세련된 디자인보다 세련된 디자인
1.3 중용의 대가 이해
중용은 일종의 기묘한 물건으로 의존성과 복잡도를 높이는 대가도 만만치 않다. 이런 대가들은 때때로 그 도움을 상쇄하기에 충분하다.
1.4 계약에 따른 프로그래밍
방법은 쌍비 간의 계약을 호출한다.계약은 호출자가 반드시 방법의 전치 조건을 준수해야 하며 방법도 이와 관련된 후치 조건을 만족시키는 결과를 되돌려야 한다.
적당한 공공방법에서는 이상과 단언으로 전치조건과 후치조건을 점검해야 한다.방법의 시작점.기타 코드가 실행되기 전에 방법의 끝에 있는 선행 조건을 검사합니다.방법은 이전 검사 후 설정 조건을 되돌려줍니다.
슈퍼클래스 방법을 덮어쓴 클래스에서 새로운 클래스를 파생할 때, 슈퍼클래스 방법의 선행 조건과 후행 조건을 보존해야 한다.이를 확보하기 위해 모형 제작 방법으로 모델을 디자인할 수 있다.공공 방법은 모두 선행 조건을 테스트하고 관련된 허위 방법을 호출한 다음에 후치 조건을 테스트한다.하위 클래스는 허를 덮어쓰는 방법을 통해 슈퍼 클래스의 공공 행위를 덮어쓸 수 있습니다.
public class LinkedList<T>

  {

   public void Prepend(T t)

    {

     //      

     Debug.Assert(... ) ;

     

     DoPrepend( t );

   

      //      

      Debug.Assert( Object.Equals(this[0],t));

  

     }

 

    protected virtual void DoPrepend( T t)

    {

       ...

    }

  }



public class Stack<T> : LinkedList<T>

 {

   protected override void DoPrepend(T t)

  {

   ...

  }

 }

1.5 적합한 공사 방법 선택
당신의 프로젝트에 적합한 소프트웨어 설계 방법을 선택하는 것을 고려하세요.각종 디자인 방법은 최상의 실천을 총결하여 소프트웨어 프로젝트의 실패를 자주 초래하는 결함과 의사소통 부족을 피했다.예를 들어 민첩한 소프트웨어 개발, 극한 프로그래밍 등이다.
1.6 다른 편집 레이어 구분
서로 다른 편집층을 분리하여 더욱 유연하고 유지 보수가 쉬운 구조를 만들다.
2. 유형의 디자인
2.1 클래스 단순화
어떤 방법이 필요한지 확인하면 추가하지 마십시오.만약 다른 방법이나 방법의 조합이 같은 기능을 효과적으로 완성할 수 있다면 방법을 추가하지 마세요.첨가 방법은 쉬워도 제거하는 방법은 어렵다.
2.2 파생류를 정의하여 사용기 조상류에 사용할 수 있도록 한다
덮어쓰기를 통해 부류의 행위를 수정하거나 제한하는 파생류는 이 종류에 대한 특화(specialization)이지만 그 실례화는 조상류의 실례를 유한하게 대체할 수 있을 뿐이다.부류를 사용하는 모든 곳에서 특화류를 사용할 수 있는 것은 아닐 수도 있다.
행위상 조상류와 호환되는 파생류는 씨앗 유형으로 그 사례는 부류의 실례와 완전히 대체할 수 있다.하위 유형의 파생류를 실현하는 것은 그 조상류를 덮어쓰지 않고 조상류의 서비스만 확장한다.하위 유형은 부모 유형과 같은 특성과 관련 관계를 가지고 있다.
리치 대체 원칙
초클래스를 인용하는 방법을 사용하려면 반드시 하위 클래스의 대상을 모르는 상황에서 하위 클래스의 대상을 사용할 수 있어야 한다.
  The Liskov Substitution Principle
      Methods that use references to superclasses must be able to use objects of subclasses without knowing it.
개방-폐쇄 원칙
소프트웨어 실체, 예를 들어 클래스, 모듈, 함수 등 대응 확장 방법.수정은 닫힙니다.
  The Open-Closed Principle
   Software entites,i.e. casses,modules, functions ,and so forth ,should be open for extension ,but closed for modification.
public abstract class Shape

 {

   public abstract void Reseize( double scale);

 }



public class Rectangle : Shape

 {

  protected double width_;

  protected double height_;



  public double Width

  {

  get

    {

        return width_;

    }

   set

    {

    width_ =  value;

    }

  }

pubic double Height

 {

  get 

  {

    return height_;

  }

  set

   {

   height_ =  value ;

   }

 }

public override void Resize ( double scale)

  {

   this.Width *= scale;

   this.Height *= scale;

  }

 }
public class Square : Rectangle

  {

    public double Size

       { 

         get

            {

             return width_ ;

             }

          set

             {

             width_ = value ;

             height_ = value ;

              }

          }

  }

정사각형의 너비와 높이는 같기 때문에, Rectangle 클래스를 수정하는 것을 고려할 수도 있습니다.
public class Rectangle : Shape

  {

    ...

   public virtual double Width

      {

         get

           {

             return width_ ;

           }

         set

            {

             width_ =  value ;

            }

      }

    public virtual double Height

      {

         get

           {

             return height_ ;

          }

          set

          {

         height_ = value ;

          }

      }

  } 



public class Square : Rectangle 

 {

   public override double Width

   {

     get 

       {

              return width_ ;     

       }

      set

        {

              width_ = value ;

              height_ = value ;

         }

   }



   public override double Height

   {

     get 

       {

              return height_;     

       }

      set

        {

              width_ = value ;

              height_ = value ;

         }

   }

 }

문제를 해결할 수 있지만 Rectangle 상위 클래스를 수정해야 합니다.코드를 수정해야 한다는 개방-폐쇄 원칙에 어긋난다.
public class Canvas

  {

      public void DrawShape(Shape shape)

        {

           if (shape is Circle)

             {

                DrawCircle( shape as Circle) ;

             }

           else if (shape is Rectangle)

             {

                DrawRectangle(shape as Rectangle);

             }

        }

      public void DrawCircle(Circle circle){...}

      public void DrawRectangle(Rectanglerectangle){...}

  }

상례는 좋지 않은 디자인이다.
public abstract class Shape

  {

    ...

    public abstract void DrawSelf (Canvas canvas) ;

    ...

  }



public class Circle : Shape

  {

    ...

       public override void DrawSelf(Canvas canvas) {...}

    ...

  }



public class Canvas

  {

  ...

   public void DrawShapes (IEnumerable<Shape> shapes)

     {

        foreach(Shape shape in shapes)

          {

            shape.DrawSelf(this);

          }

     }

  ...

  }

2.3 "is-a"관계에 대한 계승, "has-a"관계에 대한 사용 포함
예를 들어 트럭에는 (has-a)조의 타이어가 있는데 아이스크림을 운송하는 트럭은 (is-a) 중 특수한 종류의 트럭이다.
public class Wheel

  {

  ...

  }

public class Truck

  {

     private Wheel [] wheels_ ;

  }



public class IceCreamTruck : Truck

  {

     ...

  }

2.4'is-a'관계에 추상적인 기류를 사용하고'실현'관계에 인터페이스를 사용한다.
기본 클래스를 사용하여 클래스 간의'is-a'관계를 가리키고 인터페이스를 사용하여 실현 관계를 가리킨다. 
클래스와 인터페이스 사이를 선택할 때 다음과 같은 몇 가지를 기억해라.
클래스는 필드와 방법의 기본 구현을 포함할 수 있으며 인터페이스는 방법 서명만 정의합니다.
유비 인터페이스는 확장하기 쉽다. 새 구성원에 가입할 때 파생 유형을 파괴하지 않고, 인터페이스를 확장할 때 이 인터페이스를 실현하는 기존 유형을 파괴할 수 있다.
클래스는 하나의 기본 형식만 있을 수 있지만, 임의의 수량의 인터페이스를 실현할 수 있다
3. 라인 보안 및 동시 연결
3.1 리셋 가능한 설계
단일 스레드가 순환적으로 호출되거나 다중 스레드가 동시에 호출될 때 모두 정상적인 코드가 작동할 수 있습니다.즉 정적 분배 자원을 사용하지 말라는 것이다.
3.2 적절한 장소에서만 스레드 사용
여러 이벤트에 동시에 응답
높은 응답 능력 제공
멀티프로세서 사용
3.3 불필요한 동기화 방지
4. 효율
4.1 게으름 값 구하기와 게으름 초기화 사용
결과가 필요하기 전에 복제된 계산을 하지 마세요.항상 플러그 가장자리에 가장 가까운 곳에서 계산을 실행합니다.가능하면 캐시 결과입니다.
public class LoanCalculator

  {

  //...

  }

public class PersonalFinance

  {

   private LoanCalculator loanCalculator_ = null ;



   public double CalculateIntest ()

    {

         //                  

         if(loanCalculator_  == null)

            {

                  if(loanCalculator_  == null)

                      {

                             loanCalculator_  = new LoanCalculator();

                      }

             }

     return loanCalculator_ .CalculateIntest () ;

    }

  }

4.2 재분배를 피하기 위해 대상을 다시 사용한다
빈번하게 만들어지고 주기가 제한된 대상을 캐시하고 다시 사용합니다
구조 함수 대신 액세서리를 사용하여 대상을 다시 초기화합니다. 
공장 설계 모델을 사용하여 캐시와 재사용 대상 메커니즘을 봉인한다.
4.3 마지막으로 최적화
최적화 제1원칙:
최적화하지 마세요.
최적화 제2원칙(전문가에게만 유효)
최적화를 하지 않는 것이 좋다.
최적화가 필요하다는 것을 확인하기 전에 시간을 들여 최적화를 하지 마라.
80-20원칙을 채택: 시스템에서 20%의 코드는 80%의 자원을 사용한다.최적화를 하려면 그 20퍼센트 코드부터 확인해 보세요.
4.4 불필요한 객체 작성 방지
자신이 무엇을 필요로 하는지 알기 전에 대상을 만드는 것을 피하세요.
4.5 쓰레기 재활용 처리
 

좋은 웹페이지 즐겨찾기