본문 바로가기
공부 기록

[JAVA] Next Step 문자열 계산기 만들기 2

by 타태 2021. 9. 1.

 

 

 

2021.08.30 - [Back-End/Java] - [JAVA] Next Step 문자열 계산기 만들기

 

[JAVA] Next Step 문자열 계산기 만들기

2021.08.01 - [실전 공부] - 모나코 에디터(온라인 코드 에디터) 스프링 부트 프로젝트에서 사용하기 (타임리프 사용 + 파일 읽어서 뿌려주기) 모나코 에디터(온라인 코드 에디터) 스프링 부트 프로젝

ktae23.tistory.com

 

 

추가 요구 사항(리팩토링)

  • 메소드가 한 가지 책임만 가지도록 구현
  • 인덴트 깊이를 1단계로 유지
  • else 사용 금지

위 요구사항을 생각하며 다시 작성한 코드

 

문자열 계산기 클래스

package stringCalculator;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class StringCalculator2 {

    public int calculator(String input) {
        int output = 0;
        String[] tmp = null;

        if (input == null || "".equals(input) || input.isEmpty()) {
            return 0;
        }
        input = input.replaceAll(" ", "");

        if (input.length() == 1) {
            return isPositive(input);
        }

        output = defaultCalculator(input);

        if(output == 0){
            output = customCalculator(input);
        }

        System.out.println("결과 : " + output);
        return output;
    }

    private int defaultCalculator(String input) {
        int output = 0;
        if(input.contains(":") || input.contains(",")) {
            System.out.println("구분자 : , or :");
            output = sum(input.split(":|,"));
        }
        return output;
    }

    private int customCalculator (String input) {
        int output = 0;
        Matcher match = Pattern.compile("//(.)\n(.*)").matcher(input);
        if (match.find()) {
            String delimeter = match.group(1);
            System.out.println("구분자 : " + delimeter);
            output = sum(match.group(2).split(delimeter));
            return output;
        }
        return 0;
    }

    private int sum(String[] tmp){
        int output = 0;
        for (int i = 0; i < tmp.length; i++) {
            output += isPositive(tmp[i]);
        }
        return output;
    }

    private int isPositive(String input){

        int number = Integer.parseInt(input);
        if(number < 0){
            System.out.println("결과 : 음수 입력 됨");
            throw new RuntimeException();
        }
        return number;
    }
}

 

문자열 계산기 테스트

import org.junit.Before;
import org.junit.Test;
import stringCalculator.StringCalculator;

import static org.junit.Assert.assertEquals;

public class StringCalculatorTest2 {

    StringCalculator stringCalculator;

    @Before
    public void setUp() throws Exception {
        stringCalculator = new StringCalculator();
    }

    @Test(expected = RuntimeException.class)
    public void calculator() {
        assertEquals(6, stringCalculator.calculator("1,2,3"));
        assertEquals(10, stringCalculator.calculator("//-\n1-2-3-4"));
        assertEquals(10, stringCalculator.calculator("//;\n1;2;3;4"));
        assertEquals(15, stringCalculator.calculator("1:2:3:4;5"));
        assertEquals(15, stringCalculator.calculator("1:2:3:  4,5  "));
        assertEquals(0, stringCalculator.calculator(":::"));
        assertEquals(0, stringCalculator.calculator("  "));
        assertEquals(0, stringCalculator.calculator(null));
        assertEquals(0, stringCalculator.calculator("\"2:-1:3\""));
    }
}
 
결과

 

 

 

책에 나온 예제를 참고하여 리팩토링을 한번 더 해보자

문자열 계산기 클래스

package stringCalculator;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class StringCalculator3 {


    public int calculator(String input) {

        if(input != null && !input.isEmpty()){
            input = input.replaceAll(" ", "");
        }

        if (input == null || "".equals(input)) {
            System.out.println("결과 : 입력 없음");
            return 0;
        }
        return defaultCalculator(input);
    }

    private int defaultCalculator(String input) {

        if (input.length() == 1) {
            return isPositive(input);
        }
        if(input.contains(":") || input.contains(",")) {
            System.out.println("구분자 : , or :");
            return sum(input.split(":|,"));
        }
        return customCalculator(input);
    }

    private int customCalculator (String input) {

        int output = 0;
        Matcher match = Pattern.compile("//(.)\n(.*)").matcher(input);
        if (match.find()) {
            String delimeter = match.group(1);
            System.out.println("구분자 : " + delimeter);
            output = sum(match.group(2).split(delimeter));
            return output;
        }
        return 0;
    }

    private int sum(String[] tmp){

        int output = 0;
        for (int i = 0; i < tmp.length; i++) {
            output += isPositive(tmp[i]);
        }
        System.out.println("결과 : " + output);
        return output;
    }

    private int isPositive(String input){

        int number = Integer.parseInt(input);
        if(number < 0){
            System.out.println("결과 : 음수 입력 됨");
            throw new RuntimeException();
        }
        return number;
    }
}

 

문자열 계산기 테스트

import org.junit.Before;
import org.junit.Test;
import stringCalculator.StringCalculator;

import static org.junit.Assert.assertEquals;

public class StringCalculatorTest3 {

    StringCalculator stringCalculator;

    @Before
    public void setUp() throws Exception {
        stringCalculator = new StringCalculator();
    }

    @Test(expected = RuntimeException.class)
    public void calculator() {
        assertEquals(6, stringCalculator.calculator("1,   2,3"));
        assertEquals(10, stringCalculator.calculator("//-\n1-2-3-4"));
        assertEquals(10, stringCalculator.calculator("//;\n1;2 ;3; 4"));
        assertEquals(28, stringCalculator.calculator("1:2:3:4:5:6:7"));
        assertEquals(23, stringCalculator.calculator("1:2,3:  4,5  :8"));
        assertEquals(0, stringCalculator.calculator(":,:,:"));
        assertEquals(0, stringCalculator.calculator("  "));
        assertEquals(0, stringCalculator.calculator(null));
        assertEquals(0, stringCalculator.calculator("2:-1:3"));
    }
}
 
결과

 

이 작은 프로그램을 만드는데도 고민이 많고 디버깅까지 했다.

확실히 직접 만들어 보는게 배우는것도 많고 재밌다.

 

이 책은 현재 인프런으로 이직한 a.k.a. 창천향로 이동욱님이 추천한 책이어서 보는 중인데 일반적인 코더 마인드에서 한 발자국 나갈 수 있게 해주는 책인것 같다.

반응형

댓글