Dev

[Next Step] 자바 웹프로그래밍 2.3 정리

VIPeveloper 2022. 8. 24. 17:09
728x90
반응형

요구사항

  • 전달하는 문자를 구분자로 분리하자
  • 각 숫자의 합을 구해 반환하자
  • 쉼표(,) 또는 클론(:)을 구분자로 가지는 문자열을 전달하는 경우 구분자를 기준으로 분리한 각 숫자의 합을 반환하
  • 커스텀 구분자를 지정하자
    • "//", "\n" 사이에 위치하는 문자를 커스텀 구분자로 사용하자
  • 문자열 계산기에 음수를 전달하는 경우 RuntimeException으로 예외처리하자

 

요구사항을 더 작은 단위로 쪼개보자

  • 개발자의 역량을 키우기에 좋은 연습이다
  • String 클래스를 활용하자

 

2.3.2를 보기 전 내가 구현한 테스트 코드 및 구현 코드

  • 알고리즘이랑 유사하다고 느꼈다.
  • 상당히 자세하고 요구사항이 쪼개지며, 예외에 대한 테스트도 꼼꼼히 작성하게 되는 느낌이었다.
  • 음수가 있으면 예외처리를 던지는 로직을 추가하였다.
  • 테스트 케이스가 추가되며 로직이 조금씩 수정되어지는 것을 느꼈다.
    • 이게 TDD인가 느꼈고 기분 좋았다.
    public int calculate(String s){
        char[] chars = s.toCharArray();
        int sum = 0;
        for (int i = 0; i < s.length(); i++) {
            if(chars[i]=='-') throw new RuntimeException();
            if(Character.isDigit(chars[i])){
               sum += Character.getNumericValue(chars[i]);
            }
        }
        return sum;
    }

테스트 코드

  • 총 7개의 테스트 코드를 사용하였다.
  • (","), (":") 및 다른 문자열로 구분되더라도 숫자만 찾아서 더할 수 있도록 했다.
  • char을 돌면서 -가 나오면 그냥 예외처리하도록 지정했다.
  • 커스텀 코드로 ("-") 가 나오면 어떻게하지..? 흠..
class CalculatorTest {
    private Calculator cal;

    @BeforeEach
    public void setup(){
        cal = new Calculator();
        System.out.println("test setUp");
    }

    @Test
    public void splitTest(){
        assertEquals(cal.calculate("1:2:3"),6);
    }
    @Test
    public void splitTest2(){
        assertEquals(cal.calculate("1,2,3"),6);
    }
    @Test
    public void splitTest3(){
        assertEquals(cal.calculate("1,2:3"),6);
    }
    @Test
    public void splitTest4(){
        assertEquals(cal.calculate("1,2"),3);
    }
    @Test
    public void splitTest5(){
        assertEquals(cal.calculate(" "),0);
    }
    @Test
    public void splitTest6(){
        assertEquals(cal.calculate("//;\n1:2,3"),6);
    }
    @Test
    public void splitTest7(){
        assertThrows(RuntimeException.class, ()->{
            cal.calculate("//;\n1:-2,3");
        });
    }

    @AfterEach
    public void tearDown(){
        System.out.println("test over");
    }
}

 

2.3.2 를 보고 난 후 코드

  • 리팩토링의 원칙을 지켜야한다.
    • 메소드는 한가지 책임을 가지도록
    • 인덴트를 1단계로 유지
    • else 사용 금지
  • 커스텀 코드로 "-" 가 나올 경우 어떻게 구현해야할지 막막했었는데 해결되었다.
  • m.find()의 부정문을 찾을 수가 없어서 else를 하나 이용하게 되었다..
  • 언듯 간단하다고 느꼈지만 결코 그렇지 않았다. 이제 해답을 보며 풀이해보자.
    public int calculate(String s){
        if(s.isEmpty() || s.equals(" ")) return 0;

        Matcher m = Pattern.compile("//(.)\n(.*)").matcher(s);
        String [] tokens;
        if (m.find()){
            String customDelimeter = m.group(1);
            tokens = m.group(2).split(customDelimeter);
        }else{
            tokens = s.split(",|:");
        }
        int sum = 0;
        for (int i = 0; i < tokens.length; i++) {
            int i1 = Integer.parseInt(tokens[i]);
            checkMinus(i1);
            sum += i1;
        }
        return sum;
    }

    private void checkMinus(int i1) {
        if(i1 <0) throw new RuntimeException();
    }
728x90
반응형