프로젝트/계산기 만들기(개인)

[Trouble shooting] 계산기 과제 - 트러블슈팅

Dream COM Ddulut 2024. 11. 20. 13:48

[Lv1, 2 계산기 구현]

1. Getter, Setter를 어떻게 사용해야하는지 몰라 튜터님께 도움을 요청드렸다.

자세한 내용: https://ddulut.tistory.com/27

 

[TIL] Getter와 Setter를 사용하는 이유를 항상 고민하자

오늘은 계산기 만들기 과제 Lv2를 구현했다.과제 안에 Getter, Setter를 활용할 것을 요구하는 내용이 있었다.  Getter와 Setter를 만드는 법은 아니까 배운대로 척척 만들었는데, 완성 된 코드를

ddulut.tistory.com

 

2. git hub 업로드후 merge 과정에서 오류 발생

git hub에 calulator라는 새로운 브랜치를 만들어서 Lv2 코드를 업로드했다.

이후 완성 된 코드를 main branch에 merge하는 과정에서 ' There isn’t anything to compare.'라는 문구가 나오면서 merge가 되지 않았다.

검색해본 결과 main branch와 calculator branch 사이에 상관관계가 없어서 merge를 거부당한 것이었다.

참고한 블로그: https://m.blog.naver.com/ehdgnstla/223098500187

 

(GitHub)There isn’t anything to compare. main and sim are entirely different commit histories.

(서론) GitHub에 익숙하지 못한 나는 항상 GitHub을 다루어야 할때 뚱땅거린다.. 대학 팀프로젝트를 진...

blog.naver.com

 

문제 해결을 위해 chatGPT가 제시한 여러 방법을 시도해보았다.

① 공통된 조상 만들기

②  강제 병합 시도하기

하지만 전혀 소용이 없었다.

 

결국 어떤 방법으로도 문제가 해결되지 않아 gitHub레포지토리를 지우고, 새로운 레포지토리를 생성해서 파일을 처음부터 다 업로드하였다..

 

이런 문제가 발생한 원인으로 새 프로젝트를 시작할 때 git pull을 하지 않아서라고 짐작하고있다.

이 사건을 계기로 git pull을 매번 꼭 해주고있다.


[Lv3 계산기 도전]

1. 객체 지향 설계가 미흡함

다른 분들과 계산기 설계에 대해 이야기하던 중 내가 만든 클래스의 개수가 다른 사람들에 비해 현저하게 적다는 것을 인식하게 되었다. 

클래스가 적은게 문제라기보다는 그만큼 '객체지향 설계가 제대로 안 되어있다'라고 문제를 인식하였다.

 

그래서 원래는 App, Calculator, InputData 이렇게 3개로 나눠진 클래스를 더 세분화하기로 했다.

 

App에서는 계산기만 실행되도록하였고, Calculator에서 계산기의 구체적인 동작을 구현하였다.
InputData(DataHandler로 이름 변경)는 사용자로부터 데이터를 전달받는 기능만 수행하고,

NewCalulate라는 새로운 클래스를 만들어 사칙연산 기능을 따로 빼두었다.

 

원래는 아래 설계처럼 세세하게 만들고싶었는데, 코딩을 하면서 캡슐화나 컴파일에러 등 여러가지를 신경쓰다보니 제대로 구현하지 못했다....

해보고 싶은건 많았으나 실현하지 못한..

 

애초에 Lv2를 구현하면서 객체 지향 설계를 더 신경썼어야했는데, 요구사항만 열심히 반영하다 보니 Lv3에서 제네릭, 예외처리 등을 하면서 코드를 다 갈아엎게 되었다. 또한 결과적으로 갈아엎는 것 조차 제대로 못한 결과물이 나왔다..

 

아직 객체 지향에 대한 이해도가 부족한 것을 인정하고, 다음 과제에서는 시작 전에 꼭 제대로된 객체 지향 설계를 하고 코드를 작성하기로 다짐한다.

 

2. 변수명, 클래스명, 메서드명이 전달하는 의도가 불분명함

한 동료분께서 코드를 보고 작성된 이름들의 의도가 불명확하고 오해의 여지가 있다고 피드백을 주셨다.

이름을 짓는 관례에 대해 알려주셨는데 간략하게 정리해본다.

① 메서드명은 일반적으로 동사가 먼저온다.
② 클래스명이 동사로 시작하면 메서드로 오해할 수 있다.
③ 복수형 명사는 컬렉션 느낌을 준다.
④ get, set은 가능하면 Getter,Setter에만 사용하자.

 

피드백을 수용하여

클래스 InputData는 DataHandler로,

제네릭 클래스 Numbers는 GenericNumber로, 

메서드 inputNumber()는 requestNumberInput()으로 변경하였다.

 

추가로 requestNumberInput()의 흐름제어를 위한 메서드를 따로 만들었는데,

흐름제어만을 위한메서드를 따로 만드는건 좋지 않은 것 같다고 하셔서 requestNumberInput()에 합치는 작업도 수행하였다.

 

3. 열거형에 기호만 단독으로 사용할 수 없음

MathOperator라는 연산자만 저장하는 열거형 클래스를 따로 만들었다.

아래 코드 처럼 기호만 넣어서 사용하고싶었는데, 특수문자는 유효한 식별자가 아니라는 이유로 컴파일 에러가 났다.

public enum MathOperator {
    +,-,*,/
}

 

그래서 아래와 같이 변경하였다.

public enum MathOperator {

    PLUS("+"), MINUS("-"), MULTIPLE("*"), DIVISION("/");

    private final String operator;

    MathOperator(String operator){
        this.operator=operator;
    }

    public String getOperator(){
        return operator;
    }

}

 

근데 이렇게 바꾸고 나니 사용자가 +,-,*,/ 등의 올바른 기호를 연산자로 입력했음에도 불구하고, requestOperatorInput()메서드에서 IllegalArgumentException 에러가 발생했다.

String requestOperator() throws IOException{
        while(true) {
            try {
                String operator = br.readLine();
                MathOperator mathOperator=MathOperator.valueOf(operator);
                return mathOperator.getOperator();
            } catch (IOException e) {
                throw new RuntimeException(e);
            } catch (IllegalArgumentException I) {
                System.out.println("죄송합니다. 지원하지 않는 연산자입니다.");
            }
        }
    }

 

 

그래서 결국 switch 문으로 각각의 연산자에 맞는 열거형 값을 mathOperator에 넘겨주도록 수정하였는데.. 열거형을 이렇게 쓰는게 의미가 있나..? 어떻게 더 잘 사용할 수 있을까? 하는 의문만 남았다..

String requestOperator() throws IOException{
        while(true) {
            try {
                String operator = br.readLine();
                switch(operator){
                    case "+":
                        operator="PLUS";
                        break;
                    case "-":
                        operator="MINUS";
                        break;
                    case "*":
                        operator="MULTIPLE";
                        break;
                    case "/":
                        operator="DIVISION";
                        break;
                }
                MathOperator mathOperator=MathOperator.valueOf(operator);
                return mathOperator.getOperator();
            } catch (IOException e) {
                throw new RuntimeException(e);
            } catch (IllegalArgumentException I) {
                System.out.println("죄송합니다. 지원하지 않는 연산자입니다.");
            }
        }
    }

 

4. merge과정 중 충돌 발생

main branch와 calculater branch를 병합하는 과정에서 충돌이 발생했다.

충돌은 App.java 파일에서 일어났다. 

처음에는 github가 제안한 방식대로 명령어를 입력했는데 아래와 같이 에러가 발생했다. 

브렌치명 오른쪽에 ' |MERGING' 이런식으로 뭐가 생긴 것도 처음 봤다.

0000@□□□□□□ MINGW64 ~/Documents/CalculatorProject/src/Calculators (calculator|MERGING)
$ git pull origin main
error: You have not concluded your merge (MERGE_HEAD exists). hint: Please, commit your changes before merging. fatal: Exiting because of unfinished merge.

 

더이상 git pull도 안 되고 <<<<<<<, =======, >>>>>>> 표식도 안 떠서, 여차저차 문제되는 부분은 수정하고 다시 해결방안을 검색해보았다.

 

git status를 입력하니 아래처럼 메시지가 나왔다.


0000@□□□□□□ MINGW64 ~/Documents/CalculatorProject/src/Calculators (calculator|MERGING)
$ git status
On branch calculator All conflicts fixed but you are still merging. (use "git commit" to conclude merge) Changes to be committed: modified: App.java Changes not staged for commit: (use "git add <file>..." to update what will be committed) (use "git restore <file>..." to discard changes in working directory) modified: App.java

 

'충돌이 해결되었지만 merge가 아직 완료되지 않은 상태'라는 의미로 충돌을 해결한 파일을 스테이징하지 않은 상태라고 했다. 

이후 문제가 됐던 App.java를 add, commit, push 하고나서 파일을 main branch에 정상적으로 병합할 수 있었다.

 


다사다난하고 여전히 문제가 많은 첫 개인 프로젝트지만 아래와 같이 얻은 교훈은 많다.

코드는 혼자 짜는게 아니다. 여러 사람이 다같이 짜기 때문에 다른 사람이 이해하기 쉬운 코드, 오해가 생기지 않는 코드, 유지보수하기 좋은 코드를 짜도록 하자!!

이번 계산기 만들기 개인 과제에서는 '내 코드를 누가 유지보수 하게 된다면 문제가 안 생길까?'을 염두해두고 코드를 작성하자!!

이런 부분은 지나치치 말자! ’하.. 내가 친절하게 양의 정수 입력하라고했는데 서어얼마 다른 이상한걸 집어넣지는 않겠지..?’하는 의문이 든다면 그 부분은 내가 아무 사고도 나지 않도록 막아야하는 부분이다!! 사람은 누구나 실수를 한다. 아무도 믿지마라! 나도 믿지마!..