반응형

▶ 클래스 설계 요령 ◀

 

1. 데이터는 항상 private로 한다.

    이것은 매우 중요하다. 다른 식으로 하면 캡슐화가 깨지고 만다. 가끔 접근자나 변경자 메소드를 추가로 만들어야 하지만, 그래도 인스턴스 필드를 private로 만드는 것보다 훨씬 낫다. 데이터가 설명되는 방법이 변할 수도 있지만 사용되는 방법은 잘 변하지 않는다. 데이터가 private이면 그러한 설명의 변화는 클래스의 사용자에 영향을 미치지 않으며, 버그를 발견하기도 훨씬 쉽다.

 

2.항상 데이터를 초기화한다.

    자바는 지역 변수를 초기화 하지 않지만, 객체의 인스턴스 필드는 자동으로 초기화 한다. 하지만 이런 기본 값에 의존하지 말고 기본값을 제공하거나 모든 생성자에 기본값을 설정하는 방법으로 변수를 명시적으로 초기화해준다.

 

3. 클래스에 너무 많은 기본타입을 사용하지 말아야 한다.

    많은 기본타입의 관련된 사용을 다른 클래스로 바꾸자는 발상은 클래스를 더 이해하기 쉽고, 변경하기 쉽게 해준다. 예를 들어, Customer 클래스의 인스턴스 필드를 Address 라는 클래스로 바꾸자.

   private String street;

   private String city;

   private String state;

   private int zip;

 

 이렇게 하면, 주소가 국제 주소 쳬계로 바뀐다 해도 쉽게 이변화에 대처할수 있다.

 

4. 모든필드에 개별적인 접근자와 변경자가 필요한것은 아니다.

    사원의 급여를 가져오고 설정할 필요가있다. 물론 일단 객체가 생성되면 채용일은 변경할 필요가 없다.

 

5. 클래스 정의를 위해 표준형태를 사용한다.

    항상 다음과 같은 순서로 클래스의 내용을 나열한다.

        public 특성

        패키지 범위 특성

        private 특성

    각 영역은 다음과 같이 나열한다.

        인스턴스 메소드

        정적 메소드

        인스턴스 필드

        정적 필드

 

    선의 자바 프로그래밍 언어의 코딩 스타일 가이드는 필드를 먼저 나열하고 그 다음에 메소드를 나열하도록 권장한다. 어떤 스타일을 사용하든지 가장 중요한 것은 일관성을 유지하는 것이다.

 

6. 클래스를 아주 많은 역할로 나눈다.

     물론 "아주 많은"이라는 말은 모호하다. 하지만 하나의 복잡한 클래스를 개념적으로 더 간단한 클래스 두 개로 만들 수 있다면 그 방법을 사용해야 한다 (단 극단적으로 가면 안된다. 가각 한 메소드만 포함하는 클래스 10개는 지나치다는 것이다)

다음 예는 잘못 설계된 클래스이다

 

     public class CardDeck{   //잘못된 설계

           private int[] value;

           private int[] suit;

 

           public CardDeck(){....}

           public void shuffle(){......}

           public int getTopValue(){......}

           public int getTopSuit(){.....}

           public void draw(){......}

     }

 

     이 클래스는 두개의 분리된 개념을 구현하고 있다.. 하나는 shuffle과 draw메소드를 갖는 한벌의 카드(deck of cards)이며, 다른 하나는 card로 값과 카드의 패를 검사하는 메소드를 가지고 있다. 이것은 각각의 카드를 표현하는 Card 클래스를 도입하는 것은 의미가 있다. 이제 독자적인 임무를 갖는 두 클래스를 살펴보자

 

      public class CardDeck{

           private Card[] cards;

 

           public CardDeck(){...}

           public void shuffle(){.....}

           public Card getTop(){......}

           public void draw(){.......}

      }

 

      public class Card{

           private int value;

           private int suit;

 

           public Card(int aValue,itn aSuit){...}

           public int getValue(){.....}

           public int getSuit(){......}

     }

 

7. 클래스와 메소드의 이름은 그 임무에 맞게 부여한다.

    변수는 그것이  표현하는 것을 나타내는 의미 있는 이름을 가져야 하듯이 클래스도 마찬가지이다 (표준 라이브러리는 시간을 서술하는 Date 클래스처럼 약간 미심쩍은 클래스를 포함하고있다).Order  같은 명사를 사용하거나, RushOrder 처럼 선행 형용사를 수바한 명사 또는 Billing-Address 와 같은 동명사로 클래스 이름을 부여하는 것은 좋은 규칙이다. 메소드에 대한 표준 규칙은 접근자 메소드는 getSalary 처럼 소문자 get으로 시작하고, 변경자 메소드는 setSalary처럼 소문자 set으로 시작하는 것이다.

+ Recent posts