ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 함수(메소드)
    코드 성장 이야기/박재성 - TDD, Clean Code with java- 10기 2020. 12. 2. 23:44
    반응형

    github.com/rlawls1991/java-ladder

     

    위의 코드를 보게 된다면 내가 아래의 규칙을 최대한 지키면서 개발을 하였다.

     

    코드를 보고 싶으면 

     

    현 시간 기준(2020-12-02-11:15)으로 step2를 보면 된다.

    2020-12-02-11:15

     

    실행 결과

     

     

    함수(메소드) 

    1. 작게 만들어라

    • 함수를 만드는 첫째규칙은 '작게'다. 함수를 만드는 둘째 규칙은 '더 작게'다.

    2. 한 가지만 해라

    • 함수는 한가지를 해야한다. 그 한가지를 잘 해야 한다. 그 한가지만 해야한다.

    3. 함수 당 추상화 수준은 하나로

    • 함수가 확실히 '한가지' 작업만 하려만 함수 내 모든 문장이 동일한 추상화 수준에 있어야 한다.
    • 코드는 위에서 아래로 이야기처럼 일해야 좋다.

    4. side effect를 만들지 마라.

    • side effect는 실행 중에 어떤 객체를 접근해서 변화가 일어나는 행위(라이브러리 I/O, 객체 변경 등)

    5. 명령과 조회를 분리하라.

    • 함수는 뭔가를 수행하거나 답하거나 둘 중 하나만 해야 한다. 둘 다 하면 안된다.
    • 개체 상태를 변경하거나 아니면 개체 정보를 반환하거나 둘 중 하나다.

    6. 블록과 들어쓰기는 1개만

    • 하나의 메소드에 for문 안에 if문이 반복적으로 존재하게 된다면 코드를 읽기가 힘들기 때문에 1개만 작성해야 한다.

     

    1, 2, 3, 5 예시 및 설명

    아래의 코드를 보게 된다면 최대한 코드를 짧게 만들면서 메소드가 하나의 기능만 행하게 만들었다.

    또한 명령과 조회를 분리를 하였기 때문에 단일책임원칙을 지킬 수가 있었다.

    2020/03/19 - [Java/기본상식] - 객체 지향적 5대원칙(SOLID)

     

    4 예시 및 설명

    side effect는 addPoint 메소드를 보면 된다.

    즉 하나의 이벤트가 일어나고 더 이상 변화를 못하게 return을 했기 때문에

    아래의 코드에서 필요없는 추가를 막았다.

     

    6 예시 및 설명

    블록과 들어쓰기는 1개만 작성 예시는 initLineList를 보면된다. 

    for문 안에 if문이 들어오게 된다면 들어쓰기가 2개가 되기 때문에 메소드로 분리하여 코드를 작성하였다.

     

     

    package ladder.domain;
    
    import java.util.ArrayList;
    import java.util.List;
    import java.util.Random;
    
    public class Line {
    
        private static Random random = new Random();
    
        // Line 은 라인사이의 있는 상태를 뜻하므로 -1 을 해줌
        private static int SUBTRACT_NUMBER = 1;
    
        /*
         * true가 사다리 사이 이어짐
         * false가 이어지지 않음
         * ex) List에 담긴 값이 차례대로 true, false, true 일 때 아래와 같이 존재
         * |----|    |----|
         * true가 연속으로 나올 수 없다.
         * ex) 불가! |----|----|
         */
        private List<Boolean> points = new ArrayList<>();
    
        public Line(final int countOfPerson) {
            initLineList(countOfPerson);
        }
    
        private void initLineList(final int countOfPerson) {
            for (int i = 0; i < countOfPerson - SUBTRACT_NUMBER; i++) {
                addPoint();
            }
        }
    
        private void addPoint() {
            if (points.size() == 0) {
                points.add(random.nextBoolean());
    
                return;
            }
    
            checkPointRepeat();
        }
        
        private void checkPointRepeat(){
            //연속으로 true가 나올경우
            if (this.points.get(points.size() - 1) == true) {
                this.points.add(false);
    
                return;
            }
    
            points.add(random.nextBoolean());
        }
    
        public List<Boolean> getPoints() {
            return points;
        }
    }

     


     

    7. 함수 인수

    • 함수에서 이상적인 인수 개수는 0개(무항)이다. 다음은 1개이고, 다음은 2개이다.
    • 3개는 가능한 피하는 편이 좋다.
    • 4개 이상은 특별한 이유가 있어도 사용하면 안된다
    • 인수가 2 ~ 3개 필요한 경우가 생긴다면 인수를 독자적인 클래스를 생성할 수 있는지 검토해 본다.

    8. 오류 코드보다 예외를 사용하라.

    • 오류 처리도 한 가지 작업이다.
      • 함수는 '한 가지' 작업만 해야 한다. 오류 처리도 '한 가지' 작업에 속한다.
      • 그러므로 오류를 처리하는 함수는 오류만 처리해야 마땅하다.
    • try/catch 블록은 원래가 추하다. 코드 구조에 혼란을 일으키며, 정상적인 동작과 오류 처리 동작을 뒤섞는다. try/catch 블록을 별도 함수로 뽑아내는 편이 낫다.

     

    7 예시 및 설명

    아래의 코드를 보면 파라미터는

    최대한 최소한으로 줄었다는 것을 볼 수가 있다.

     

    8 예시 및 설명

    name의  exception처리는 별도의 함수를 생성하여 아래와 같이 작성 하였다.

     

    public class Names {
        private static int MAX_NAME_LENGTH = 5;
    
        private List<String> names = new ArrayList<>();
    
        public Names(final String names) {
            initNames(names);
        }
    
        private void initNames(final String names) {
            List<String> tempNames = Arrays.asList(names.replaceAll(" ", "").split(","));
    
            checkName(tempNames);
    
            this.names = tempNames;
        }
    
        private void checkName(final List<String> tempNames) {
            isEmpty(tempNames);
    
            for (String name : tempNames) {
                checkNameLength(name);
            }
        }
    
        private void isEmpty(final List<String> tempNames){
            if(tempNames.size() == 0){
                throw new RuntimeException(ErrorMessage.getCheckInputNames());
            }
        }
    
        private void checkNameLength(final String name) {
            if (name.length() > MAX_NAME_LENGTH) {
                throw new RuntimeException(ErrorMessage.getCheckNameLength());
            }
        }
    
        public List<String> getNames() {
            return names;
        }
    }

     


     

    10. 반복하지 말아야 한다.

    • 위의 코드들을 보게 된다면 반복되는 기능들이 없다. 하지만 반복적인 행위가 계속 들어가게 된다면 코드는 매우 보기가 불편해 질 것이다.
    • 중복은 소프트웨어에서 모든 악의 근원이다.

     

     

    반응형
Designed by Tistory.