[Error] 계산기 만들기 트러블 슈팅

2025. 10. 17. 11:58Dev./Error.

728x90
반응형

기능 구상

Level1. 클래스 없이 만드는 계산기

  • 양의 정수 2가지 , 사칙연산기호 한가지 입력
    • 양의정수는 각각 하나씩 입력, 정규식 검사 후  int 타입으로 변수에 저장
    • 사칙연산 기호는 char 타입으로 변수 저장
  • 연산 진행
    • switch문을 사용해 각 연산자에 맞게 진행
    • 나눗셈 연산에서 두번째정수에 0이 입력될 경우 오류 출력
  • exit 문자열 입력 전까지 계산 진행
    • 각각의 인풋값 입력단계에서도 exit 입력시 연산 끝낼 수 있도록 로직 작성
    • 각각의 계산이 종료될때도 exit 입력할 수 있도록 작성
    • 대소문자 관계없이 비교하는 String.equlsIgnoreCase를 발견해서 적용

Level2. 객체 지향 계산기

  • 기능으로 클래스 분리 
  • Calculator 클래스
    • 사칙연산 수행
    • 인풋값 입력시 검증 메소드
    • 결과값 반환, 연산 결과 리스트는 ArrayDeque로저장
    • 연산결과 저장 필드는 접근제어자 private 사용
  • CalculatorApp 클래스
    • 연산부분 제거
    • 연산 결과값은 getter 메소드로 출력
    • 연산 결과값은 각연산의 메소드에서 저장
    • 계산기 종료 전 가장 앞에 입력된 값 제거하고 출력

Level3. 진짜진짜 객체 지향 계산기

  • 객체지향 특징(추상화, 캡슐화, 상속, 다형성) 에 위배되지 않도록 설계
  • 기존 Calculator 클래스에서 연산, 결과조회, 저장 다함 -> 클래스 분리
  • OperatorType (enum) 클래스 - enum 매핑
    • 내부 getOperator 호출시 전달받은 연산기호와 맞는 enum 상수 리턴
    • 속성 필드 private로 연산을 위한 getter 메소드
  • Operators 클래스 - 연산 기능
    • 속성은 전역으로 사용하고싶어서 public 설정
    • 람다식으로 필드 초기화
    • 두개의 double 값을 받아 double로 반환한다는 규칙의 내부 인터페이스 추가
    • 속성 초기화할때 기존 enum 맵핑에 사용했던 람다식 넣어줌
  • ArithmeticCalculator 클래스 - 결과 조회/저장
    • 기존 연산을 enum의 apply 메서드에서 수행
    • 기존 ArrayDeque ArrayList로 수정 ( Lv2 가장 오래된값 삭제하는 메소드 동시에 제거)
    • 실수까지 계산 가능하도록 제네릭 Number 로 변경
  • ArithmeticCalculatorApp 클래스 - 입출력
    • filterResults를 호출해 간접 접근으로 사용자가 입력한 값보다 큰 결과 리스트 가져옴

가장 많았던 에러

1. NullPointException

NullPointerException

값에대한 null 트러블 이슈도 많았지만 그부분은 디버깅시 바로 해결할 수 있었다.

가장 시간을 잡아먹었던 null 오류는 Calculator 클래스 생성자 초기화 부분이었다. Level2 과제할때부터 속성도 선언하고  예제대로 생략 가능한 생성자도 작성해서 초기화해주었다.  중간부터 생략가능한 생성자 초기화 코드를 지우고 속성에서 바로 필드 초기화를 해주어야했는데 코드만 지운것이다. 이후 this.results로 값을 불러오기만 하면 null이 생기는데 구글링하면 필드를 선언하고 생성하는 부분 확인하라고 해서 보면 선언은 되어있으니 초기화 했다고 착각했다.  

2. IllegalStateException

Exception in thread "main" java.lang.IllegalStateException: Scanner closed

레벨 단계에 맞춰 이전 코드에서 계속 수정에 수정을 하다보니 위치가 많이 변경되어 에러가 많이 났다.

또한 로직 중간에 조건으로 분기시키며 바로 닫아버리고 싶은 맘에 총 두 번의  스캐너를 닫는 과정도 발생했었다. 스캐너는 하나의 클래스에서 한번만 닫을 수 있다는 사실을 상기하며 코드 수정했다.

가장 어려웠던 부분

Lv1.

  • 익숙하지 않은 자바문법

Lv2.

  • 새로짜는거보다 기존 코드 수정하는게 힘듬
  • 클래스 필드가 private로 변경되며 간접 접근하는 getter와 setter의 활용 - 처음에 getter는 잘 적용해놓고 값 저장할때 잘 보호해놓은 필드 그냥 막 접근해서 저장해버림 
  • ArrayList 와 ArrayDeque -  고민하다 과제가 맨처음 값을 삭제하라고 해서 ArrayDeque 사용했다.

Lv3.

  • 디버깅 시작 파일 위치 실수 - 파일이 늘어나니 위치가 꼬였다. 반드시 현재파일기준으로 돌아가는지 확인하자!!
  • enum - 파이썬에선 그냥 상수 집합이었는데 클래스라 개념이 좀 어려웠다. enum 타입은 전역으로 관리하고 싶어서 클래스 밖으로 뺐다고 생각했는데 내가봐도 이상해서 튜터님께 질문하니 이런위치는 개발인생처음이라고 하심. 
  • 인터페이스&다형성 - 똑같은 타입의 계산이 기호만 바뀐다. 한번에 관리하기 위해 두개의 double 값을 받아 double로 반환한다는 규칙의 내부 인터페이스 추가하고 계산 호출시 속성에 람다식으로 연산값 담기도록 수정

git

  • 과제 레벨별로 브랜치를 분기해 관리하고있었던 상태에서 문서화 작업을 하다 실수로 README 파일을 가장 최신 브랜치에 푸시했다. 머지가 된 상황이 아니라 main에는 보여지지 않게되어 특정 커밋만 cherry-pick으로 가져와 수정했다.과제여도 땀줄줄남
git log --oneline --graph --all 

| * abced01 [Level3]  [Level3] README 파일 작성 		>>내가 필요한 커밋 id
| * abced01 [Level3] 객체지향적 설계 리팩토링, 클래스 설명 추가
| * abced01 [Level3] 예외처리

git cherry-pick abced01
git commit --amend -m "README 파일 작성" 			>> 커밋명에 브랜치 머릿말 제거
git push origin main

 

728x90
반응형