[project]Calculator_TIL

기 원·2025년 2월 27일

프로젝트를 성공적으로 끝마치고 그간 있었던 문제와 해결방법을 간략히 작성하였다.


Calculator_1

  1. if(out == "exit") vs if(Objects.equals(out, "exit"))
 System.out.println("종료 하시려면 'exit'를 입력해주세요");
            String out = sc.next();
            if (Objects.equals(out, "exit")){
                break;
         	}

vs

 System.out.println("종료 하시려면 'exit'를 입력해주세요");
            String out = sc.next();
            if (Out == "exit"){
                break;
         	}

코드를 짜며, 둘 중 어떤걸 써야 할지 생각을 해보았다.

  1. if(out == "exit")
  • == 연산자는 메모리 주소값을 비교
  • out 과 exit이 동일한 메모리 주소를 가리키면 true
  • 문자열은 기본적으로 string Pool에 저장되니 true가 출력된다.
  1. if(Obhects.equals(out, "exit"))
  • 값 자체를 비교

원하는건 메모리 주소를 비교하는것이 아니라 값을 비교하는것이기에 if(Obhects.equals(out, "exit"))을 사용하였다.


Calculator_2

  1. UnsupportedOperationException
    1. 배경: 프로그램 Run중 해당 예외 발생
    1. 발단: 예외를 확인하고 해당 문제를 해결 하려 하였고
    2. 전개: 위 문제는 객체가 지원하지 않는 연산을 수행할때 발생하는 예외라는것을 알게되었다.
    3. 위기: 작성한 코드에서 어떤 부분이 문제인지 확인해야 했으며
    4. 절정: List.of()가 불변 리스트 이며 그곳에 add()를 실행함으로 예외처리 되었다는 것을 알게 되었다.
    5. 결말: 문제의 부분을 아래와 같이 변경함으로 수정을 완료하였다. 아직 불변, 가변의 개념이 부족한것 같아 해당 부분의 학습을 더욱 매진해야겠다고 생각하였다.
private static List<String> history = List.of();

불변 리스트를 만들고 그 후 add()를 실행하여 해당 예외가 나왔다.

this.history = new ArrayList<>();

위와 같이 수정함으로 fixd 하였다.

  1. 연산 후 출력 값 이상

    1. 배경: 코드 정상 작동 여부를 파악하던 중
    2. 발단: 연산 후 최근 계산값 출력에 이상이 있음을 파악하였다.
    3. 전개: 출력 부분의 문제였기에 해당 부분의 코드를 확인하였다.
    4. 위기: a + c + b라 작성한 곳에서 c가 사칙연산 기호가 아닌 연산자로 해석될 가능성이 있음을 파악하였고
    5. 절정: 해당 부분을 해결하기위해 효과적인 아이디어를 생각하게 되었다.
    6. 결말: 가장 쉽고 효과적인 방법은 사이사이에 " "을 넣음으로서 구분을 확실히 하는것이라 생각되어 " "을 사이에 추가하였다.
output = a + c + b + " = " + result;

변수 간 구분이 확실히 되지 않아 a + c + b 처리시 c가 문자열이 아닌 연산자로 해석될 가능성을 생각했고

output = a + " " + c + " " + b + " = " + result;

" "을 사이에 추가함으로 구분을 확실히 하였더니 정상 출력 되었다.


Calculator_4

  1. 변수명
    처음 프로그래밍을 배울때(약 10여년전) 변수명을 a, b, c 따위로 정하고 주석으로 설명을 적으라고 배웠는데, 요즘은 의미 있는 이름으로 변수명을 적는다고 하여 변수명을 변경 하였다.
    a => fstVal
    b => sndVal
    c => mathSymol

    이게 맞는것 같다.

  2. 가독성 및 유지보수의 편의를 위해 정수와 기호를 받는 부분을 메서드로 분리하는 작업을 진행 하였다.

  3. static

private static List<String> history; // static으로 선언

 public Calculator() {
        this.history = new ArrayList<>();
 }
private List<String> history;

 public Calculator() {
        this.history = new ArrayList<>();
}

static변수는 클래스에 속하고 모든 인스턴스가 공유한다.
static으로 지정하여 여러 객체가 같은 기록을 공유할 수 있다는 장점이 있으나 생성자 실행 시 데이터가 초기화 될 위험이 있다는 단점이 이 존재한다.

작성한 코드에서는 문제 없이 동작하지만, static변수를 꼭 써야 하는것도 아니고, 사용한다 해도 static초기화 블록을 사용하는 것이 더 효과적이여서 삭제 하였다.

  1. 잘못된 값도 history에 저장되는 문제
case '/':
	if (b == 0) {
		System.out.println("분모에는 0이 들어갈 수 없습니다." + "\n");
		break;
	}

break를 사용함으로 해당 문구를 출력하고 값을 저장하는 문제가 있었다.

case '/':
	if (b == 0) {
		System.out.println("분모에는 0이 들어갈 수 없습니다." + "\n");
		return 0;
	}

return 0으로 변경함으로 잘못된 값이 저장되는것을 막았다.

  1. 데이터 삭제 정상작동
    Main.java
calculator.removeresult(); // 오래된 데이터 삭제

데이터 삭제 부분을 Main파일에 작성하였는데, setHistory()에서 값이 추가된 후 바로 실행되지 않으면 지정한 갯수를 초과할 수 있음으로 데이터 추가 후 즉시 removeresult() 호출하는 방법으로 변경하였다.
Calculaotr.java

public void setHistory(String savedata){
        history.add(savedata);
        removeresult();
}

Calculator_5

  1. 제네릭을 활용한 문자타입 변환
    1. 배경: 제네릭을 활용하여 정수를 실수로 변환하는 코드를 작성 하던 중
    2. 발단: 타입을 직접 지정하게 되었다.
    3. 전개: 해당 방법은 제출자의 출제의도와 다르다 판단하여 튜터님을 찾아 뵙고 해당 문제의 접근방법을 여쭤 보았고
    4. 위기: 동적 변환을 기준으로 접근해 보라는 조언을 얻어 고민한 끝에
    5. 절정: 실수와 정수의 차이는 .에 있다는걸 깨닳아
    6. 결말: if문을 활용해 입력값의 .의 유무에 따라 변환하는 코드를 작성하였고, 정상작동 하였다.

제네릭(T extends Number)을 활용하여 int, double타입 모두 지원하는 코드를 작성 중

double fstVal = getdataval(sc, "첫번째 숫자를 입력하세요.", Double.class);
OperatorType operatortype = getdatasymol(sc, "사칙연산 기호를 입렵하세요(+, -, *, /)");
double sndVal = getdataval(sc, "두번째 숫자를 입력하세요.", Double.class);

위와 같이 Double.class라고 직접 지정하였다.
자동으로 변환되는게 아니라 판단되어튜터 "박성원"님께 문의를 하였고, "직접 지정한다고 접근하면 상당히 힘들다. 동적 변환으로 생각해 보라"는 답을 얻었다.

정수실수로 변환.
두개 의 차이는 .의 유무차이 라는것을 깨닳고

 while (true){
            String input = sc.next();
            try{
                if(input.contains(".")){
                    return (T) Double.valueOf(input);
                } else {
                    return (T) Integer.valueOf(input);
                }

위와 같이 if문을 활용하여 input 값에 .이 있다면 실수로 변환하고 없다면 정수로 변환하는 코드를 작성하였다.

profile
노력하고 있다니까요?

0개의 댓글