리펙토링이라는 주제와 사례를 본격적으로 다루기전에 기본적으로 알고 있어야 될 여러가지 지식 중 가장 중요하다고 생각되는 객체지향에 대해서 개인적인 소견을 다룹니다.
객체지향을 정복해야되는 이유
1. 소프트웨어 개발시 가장 많이 할애되는 시간
소프트웨어 개발 과정(단계)
소프트웨어 개발은 '분석 -> 설계 -> 구현 -> 테스트' 단계를 거치며 진행이 된다. 소프트웨어 개발에는 여러가지 방법론이 존재하는 가장 오래된 폭포수 개발 방법부터 애자일 개발 방법에 이르기까지 방법론적인 측면에서 문제점을 찾고 개선을 찾아서 발전및 적용 되어 왔다. 방법론이 나온 순서로 봤을 때 폭포수 모델이부터 애자일까지 극과 극을 달린다는 방식이라고 생각될 수 있다. 그리고 애자일은 폭포수방법론을 1도 차용하지 않는다고 말 할 수도 있다. 하지만 그 안을 살펴보면 '분석 -> 설계 -> 구현 -> 테스트' 단계는 폭포수가 되었든 애자일이 되었든 벗어날 수 없는 순서이다. 앞으로 역행이 되냐 안되냐? 잘게 쪼개서 반복적이냐? 점진적이냐? 어디에 가치를 두느냐? 의 차이가 존재 하지만 변치 않는 사실은 '분석 -> 설계 -> 구현 -> 테스트' 단계를 거치지 않고 소프트웨어 개발이 될 수는 없다는 사실이다.
개발자가 진행하는 과정(단계)
소프트웨어 개발 단계 중 개발자는 구현 및 테스트 단계를 수행하는 업무를 맡게 된다. 물론 테스트의 범위에 따라서 여러가지 테스트가 존재하고 테스트별로 그 주체가 다를 수 있지만 최소한 개발을 했으면 개발자 테스트는 거칠 수 밖에 없다. 그 과정을 거치지 않고 사용자에게 인계되는 소프트웨어는 확신 할 수 없는 제품을 인계하는 것과 같기 때문이다. 그렇다면 소프트웨어 개발 단계 2단계 중에 개발자는 '설계 -> 구현' 단계를 진행하는 것이 개발자의 임부가 된다고 할 수 있다.
개발자는 개발 과정 중 어느 부분에 시간을 가장 많이 쓸까?
우리가 개발을 하는 것을 가만히 상상해보자. 우린 어떤 문제를 해결하기 위한 설계 혹은 문제 상황을 인식 하고 그 문제를 푸기 위해서 자신의 구현에 대해서 상당히 고민을 한 후 때로는 그 고민의 과정 중에 확인을 위하여 작은 테스트 코드를 만들기도 하면서 실제 코드를 만들기 위한 여러 준비작업을 거친다. 그리고 어떻게 개발을 해야될지 판단이 서면 코딩이라는 행위를 시작하고 실제 코드를 돌려보면서 테스트를 하며 자신이 작성한 코드가 잘 돌아가는지 테스트를 한다. (물론 테스트의 가치를 매우 잘 알고 있고 TDD 추구하는 개발자라면, 테스트를 기계에 맡겨서 할 것이다.) 예상한대로고 돌아가지 않는다면 디버깅 과정을 통해서 소스 코드의 잘 못 된 부분을 수정 하기도 할 것이다.
이 과정을 딱 두가지로 나눠어 소스코드를 작성하는 과정과 소스코드를 읽는 과정으로 딱 양분한다면, 개발자는 어디에 많은 시간을 할애 할 것 같은가? 여러가지 생각이 다를 수 있지만 나의 경험으로는 소스코드를 만드는 시간보다 소스코드를 보는 시간이 더 많이 할애가 되는 것 같다. 내 경험으로는 전체 코딩 시간이 100이라고 가정한다면, 작성하는데 15~20정도의 시간? 코드를 보는데 80이상을 쓰는 것 같다.
가만히 상상을 해보자. 보통 내가 만든 코드는 한번에 돌아가지 않는다. 오히려 내가 작성된 코드가 한번에 돌아가면 더 신기해서 놀란다. 정말 한번에 돌아간 것이지 더 확인을 시도 하기도 한다. 하지만 이런 경우는 거의 없다. 어김없이 내가 작성한 코드는 한번에 내가 원하는대로 정상작동을 하지 않을 가능성이 월등히 높다.
그래서 보통 정상작동을 하기까지 디버깅 툴을 이용하여 내가 잘 못 작성한 곳은 없는지 오해를 한 부분이 없는지 확인을 하여 프로그램을 올바르게 동작하도록 코드를 수정 하는 과정을 거친다.
보는게 편해야 한다.
개발과정에서 가장 많은 시간을 쏟는 것은 보는 시간이다. 자신의 작업시간 중에 8할을 차지하는 보는 시간이 괴롭다면 소프트웨어 개발이 얼마나 힘이 빠지겠는가? 보는 시간이 괴롭다는 것은 소스코드를 보는 것이 괴롭다는 것이다. 이것이 괴롭다는 이야기는 소스코드가 제대로 읽혀지지 않아서 힘들다는 것이다. 소스코드가 복잡하고 난해하게 작성되어 있으면 보는 과정이 괴로운 것이다. 우리의 개발과정이 즐겁기 위해서는 보는 과정의 괴로움이 줄어들면 자연스럽게 즐거워 지는 것이다. 소스코드를 보는 과정이 편안하다면 일의 능률도 오를 것이다.
우리는 이렇게 보는 과정이 즐겁기 위해서 소스코드를 보기 편한 코드로 만드는 것에 많은 시간을 할애 해야된다. 처음구현테스트를 위한 코드가 처음부터 잘 짜여지고 좋은 모습으로 만들어질 수 없다. 처음에는 확인을 위해서 테스트코드나 확인용 코드가 만들어지지만 실제 제품에 들어가거나 덩치가 커지기 전에 우리는 보기 편하게 수정하는일을 꾸준히 자주 해야된다. 그래야면 바로 뒤에 보는 과정이 편해져서 개발과정 자체가 괴로워지지 않을 수 있다.
이렇게 보는 것이 괴로운 코드를 보기 좋은 코드로 만드는 과정을 우리의 선배 마틴파울러가 '리펙토링'이라고 명하였고 책 또한 발간하였다. 그 책에서는 보기 어려운 코드를 악취가 난다고 표현하였고 악취를 재거하는 과정을 설거지 과정으로 표현하고 '릭팩토링'이라 명하였다.
2. 절차지향의 한계 (객체지향이 필요한 이유)
객체지향이라는 프로그래밍 패러다임을 사용하지 않고 복잡한 코드를 정리하기 위해서 사용할 수 있는 우리의 도구는 각종 명칭과 함수 밖에 없다. 절차지향이 제공하는 두가지 도구만으로는 소스코드의 아름다운 정리에는 한계가 존재한다.
간단한 예로 두 수의 합을 구하는 함수가 있다고 하자. 그 함수에서 두개의 파라메터를 받도록 작성하였는데, 언제부터인가 파라메터가 1개 더 늘어야되는 상황이 되었다면 어떻게 할 것인가? 절차지향에서는 동일 함수명으로 파라메터가 다르게 작성할 수 있는 메서드오버로딩이라는 기법을 사용할 수 없다. 그래서 함수명을 변경해야되는 상황에 내몰릴 수 있다. (몰론 파라메터를 배열로 하면 된다. 예시로서만 봐줬으면 한다)
또, 어떠한 함수가 처리하던 행위가 때로는 전혀 다르게 처리되어야 할 때 객체지향에서 제공하는 메서드오버라이딩을 이용할 수가 없다. 또 다시 다른 함수명으로 대체하는 수 밖에 없다.
이런식으로 단순하게 명명하면되는 함수명이 여러가지 수식어가 달리는 함수명으로 명명되기 시작하면 그 함수를 호출하는 소스코드를 보는 입장에서는 엄청난 헷갈림이 발생한다. 컴퓨터가 아닌 우리 머리가 연산을 수행하며 판단을 해야되는 상황이 되는 것이다. 단순한 명칭으로 파라메터가 두개든 세개든, 함수안의 로직이 재정의 되었든 안되었든 쓰는 입장에서 하나의 명칭이면 되는 상황인데 상황마다 다른 명칭의 함수를 불러야되는 상황이 연출되는 것이다. (물론 다른 꼼수로 해결이 가능하기도 하지만 예외로 둔다)
이렇게 절차지향이 기본적으로 가지는 문제점에 대해서 이야기를 하지 않더라도 객체지향이 가지는 매우 많은 장점을 절차지향으로는 대체할 수가 없다. 현대 프로그래밍에서 소스코드를 보기 편하기 만들기 위해서는 절차지향으로는 한계가 있을 수 밖에 없다.(혹은 엄청난 꼼수가 필요하다. -> 이 꼼수는 다시 읽기 어려운코드가 되기도 함)
객체지향의 원론적인 내용을 떠나서 나는 객체지향에서 객체는 상상력의 산물이라 생각한다. 데이터와 메서드의 결함물인 클래스는 내가 만들어낸 상상력의 정의물이며 객체지는 그 상상물의 구현체이다. 그 구현체가 메모리에 올라와서 내가 원하는데로 내가 하고자 하는 대로 작동 되어 주는 것이 객체이다. 이것을 가능하게 하는 프로그래밍 패러다임이 객체지향프로그래밍이다.
리펙토링을 하기 위해서는 객체지향 프로그래밍을 떠나서는 작명 수준 이상의 목적은 달성하기가 어렵다. 읽기 쉬운 코드를 만들기 위해서는 객치지향이 꼭 필요하다.
3. 결론
개발하는 시간이 즐겁기 위해서는 보는 시간이 즐거워야 한다. 보는 시간이 즐겁기 위해서는 읽기 쉬운 소스코드를 작성해야된다. 읽기 쉬운 소스코드는 한번에 나오지 않는다. 항상 소스코드를 릭팩토링 하며 읽기 쉬운 코드로 만들어 두어야 한다. 이런 리펙토링을 쉽고 편하게 하려면 절차지향으로는 한계가 있다. 객체지향이 도입되지 않으면 리펙토링 결과의 달콤함을 맛보기 어렵다. 고로 객체지향은 피할 수 있는 산이 거나 대충 오를 수 있는 산이 아니라. 개발자라면 필수적으로 꼭대끼까지 가봐야 하는 산이다. 더해서 객체지향이 무엇인지 깊숙히 이해하고 있어야 하며 자신의 문제를 객체지향으로 대응할 수 있도록 코딩 수준을 높여야 한다.
현대 프로그래밍에서 객체지향을 대충 이해하고 정복 할 수 있는 것은 거의 없다. 객체지향 패러다임을 기반으로 작동되는 언어라면 대충 이해해서는 자신이 원하는대로 코드를 작성 할 수가 없다. 돌아가기 위한 코드를 작성하는 것에만 급급할 수 밖에 없다. 그러니 피하지 말고 꼭 이해하고 적용하고 발전 시켜 나가야 한다. 이것이 우리가 많은 시간을 할애하는 코드 읽는 시간이 편안해지도록 만들 수 있는 가장 기본적인 요구사항이다.
'Refactoring' 카테고리의 다른 글
.net Winform 에서 코드 룩업하기 리펙토링 step4 (0) | 2021.10.08 |
---|---|
.net Winform 에서 코드 룩업하기 리펙토링 step3 (0) | 2021.10.08 |
.net Winform 에서 코드 룩업하기 리펙토링 step2 (0) | 2021.10.07 |
.net Winform 에서 코드 룩업하기 리펙토링 step1 (0) | 2021.10.07 |
.net Winform 에서 코드 룩업하기 리펙토링 전제 (0) | 2021.10.07 |