Calculator_Lv3 구현에 앞서, Calculator_Lv2의 리팩토링 필요성을 절실히 느꼈다. 원래는 바로 Lv3를 진행하려 했지만, Lv2 코드가 너무 복잡하게 구성되어 있어 이를 그대로 유지한 채 다음 단계를 진행하기에는 무리가 있었다. 그래서 Lv2를 먼저 단순화하고 정리하는 작업이 필요하다고 판단했다.
이번 포스트에서는 Calculator_Lv2를 완성하면서 겪었던 몇 가지 트러블슈팅 경험을 공유해보려고 한다. 처음에는 클래스 간의 역할을 나누는 것이 가독성과 유지보수에 좋을 거라 생각했지만, 오히려 너무 나누게 되어 비효율적인 구조가 되어버렸고, 이를 해결하기 위해 다시 리팩토링을 하면서 배운 점들이 많았다.
처음 설계 단계에서는 기능별로 클래스들을 나누는 것이 가독성과 유지보수에 더 좋을 거라 생각했다. 그래서 연산 기능은 Operation 클래스, 입력 처리는 InputHandler 클래스, 그리고 계산 결과 처리는 Calculator 클래스로 나누었다.
하지만 이렇게 너무 많은 클래스로 나누게 되면서 오히려 코드 흐름이 분산되고, 각 클래스 간의 협업이 복잡해져서 가독성이 떨어지게 되었다. 특히, Operation
클래스는 불필요하게 사용되고 있어, 이를 Calculator 클래스와 InputHandler 클래스에 통합하는 것이 더 나은 선택이었다.
해결 방법:
또 하나의 중요한 문제는 잘못된 입력에 대한 처리가 여러 클래스에 나누어져 있었다는 점이다. 예를 들어, 연산자 입력 시 잘못된 연산자가 들어오면 InputHandler에서 처리하고, Calculator에서 다시 계산 시 처리하는 등 에러 처리가 중복되고 있었다.
이로 인해 코드가 지나치게 복잡해졌고, 각 클래스 간의 책임이 모호해졌다.
해결 방법:
이번 트러블슈팅을 통해 느낀 가장 중요한 교훈은, 클래스 분리는 단순히 역할에 따라 나누는 것만으로는 충분하지 않다는 것이다. 너무 세밀하게 나누면 오히려 복잡성이 늘어날 수 있고, 각 클래스의 역할이 명확하지 않으면 유지보수에 어려움을 겪게 된다.
결과적으로 불필요한 클래스는 제거하고, 필요한 역할을 명확하게 분배함으로써 간결한 구조를 만들 수 있었다. 또한, 에러 처리는 한 곳에서 일관되게 처리하도록 함으로써 코드의 유지보수성과 가독성을 크게 향상시킬 수 있었다.
Calculator_Lv2를 완성하면서 처음에는 많은 클래스와 메서드를 나누고, 책임을 분산시키려 했지만, 오히려 코드의 가독성과 유지보수성을 저해하는 결과를 낳았다. 이를 해결하기 위해 클래스를 단순화하고 입력 처리 로직을 중앙화하는 방향으로 리팩토링했고, 그 결과 더 간결하고 효율적인 코드를 만들 수 있었다.
이 경험을 통해, 코드 구조를 설계할 때는 필요 이상으로 복잡하게 분리하지 않는 것이 중요하다는 것을 다시 한 번 깨달았다.
이제 다음 단계로 Calculator_Lv3를 구현하며, 더욱 복잡한 기능들을 도입할 예정이다. 다음 포스트에서는 Enum, 제네릭, 람다 & 스트림을 활용한 계산기 구현 과정을 공유할 계획이다.