한빛 미디어 4월 도서 리뷰
“한빛미디어 <나는 리뷰어다> 활동을 위해서 책을 제공받아 작성된 서평입니다.”
2, 3월에 이어 감사하게도 한빛 미디어의 4월 리뷰어로 선정되어, 이번에는 “유연한 소프트웨어를 만드는 설계 원칙”이라는 도서를 리뷰할 수 있는 기회를 얻게 되었다.
책 이름만 들어보면, 다음 책들과 엇비슷한 내용들을 설명할 것으로 막연히 느낌이 왔었다.
- Clean Code (클린 코드)
- Refactoring (리팩토링)
- Clean Software (클린 소프트웨어)
- 쉽게 배워 바로 써먹는 디자인 패턴
위의 책에 있는 내용들은 상황별로 필요할 때마다 조금씩 사전처럼 찾아서 읽어보는 형태로 적용하고 있었는데, 여기서 언급되는 소프트웨어 설계 방법이 조금씩 포함되는 형태로 책이 구성되는 듯한 느낌을 받았다.
(실제로 소프트웨어 방법론과 관련한 내용은 겹치는 것이 많다)
문제는 책 내용이 정말 어렵고, 컴퓨터 공학적인 설명을 어떤 때는 생물학을, 또 어떤 때는 수학적 지식을 활용해 소프트웨어 확장 방법에 대해 서술하기 때문에 종종 내 메타 인지 능력을 테스트하는 듯한 느낌의 독서를 시작하게 되었다.
1. 유연한 설계란?
내가 개발하면서 정말 많이 느꼈던 것은, 주제가 정해진 프로젝트에 대해 개발을 수행할 때 기존에 정의한 문제가 변하게 될 경우 완전히 뒤엎는 경우가 종종 있었다는 것이다.
즉, 초기에 프로젝트 설계하는 부분에서 설계를 잘못하게 되면서 새롭게 작업해야하는 부분이 늘어나는 것인데, 이 책의 저자들의 목표는 요구사항의 변화에 수월하게 적응할 수 있도록 새로운 기능을 구현한 코드를 추가하거나 기존 함수를 새로운 요구 사항에 맞게 조정하는 것이 자연스러워야 한다고 언급한다.
때문에 유연성을 극대화하려면 한 부품의 출력 범위가 상당히 작고 잘 정의되어야한다는 얘기를 하는데, 이는 클린코드에서 “한 개의 함수는 한 가지 기능만 수행한다”를 언급하는 것과 거의 비슷한 얘기를 하는 것이지 않을까 싶다.
다만, 한 가지 의문인 것은 새로운 기능이나 기존 함수를 새로운 요구에 맞게 수정하는 작업이 작업을 뒤엎지 않고 동작하려면, 작업하려는 것이 굉장히 일반화 되어 있어야할 것 같은데, 이 경우 동작하는 코드가 일반화 될 수는 있어도 작업의 복잡도가 올라가는 문제가 발생한다. 어떤 식으로든 코드는 동작하겠지만, 일반화를 달성하기 위해 개발자에게 가독성이 높은 코드를 포기하는 상황이 만들어지는 것이 과연 옳은 선택인지에 대해 고민해 볼 포인트들이 있었다.
2. 영역 특화 언어 (DSL — Domain Specified Language)
영역 특화 언어, DSL, 에 대해 처음 들었을 땐, Java 스프링에서 사용하는 QueryDsl이 떠올랐다.
(스프링 프레임워크에서 사용할 수 있는 프레임워크로, 복잡한 쿼리 구문을 구성하는 것을 지원한다.)
일반적으로 Domain이 뜻하는 바는 특정한 문제를 해결하는 영역을 뜻하는데, queryDsl이라면 쿼리 도메인에 대한 특화 언어를 의미하므로 스프링에서 쿼리와 관련한 기능을 지원하는 것을 추론할 수 있다.
이러한 DSL은 서로 연관된 다양한 프로그램들을 구축하기 위한 프레임워크를 제공하는데, 실제로 QueryDsl을 사용하는 시점을 잘 생각해보면, SQL만 사용하는 일반적인 상황에서는 입력받은 쿼리나 응답으로 가져오는 데이터에 대해 타입 검사를 수행할 수 없다.
그러나 QueryDsl 등을 사용하게 되면, Java라는 언어와 함께 사용하게 되면서 입출력 값에 타입 검사를 실행할 수 있고, 서비스 안정성을 더할 수 있다는 장점을 가져올 수 있다.
(그리고 JPA로 커버할 수 없는 복잡한 쿼리를 구성할 때도 아주 매력적이다)
3. 함수형 언어를 사용한 실습
스킴(Scheme)이라는 프로그래밍 언어를 사용해 실습 코드를 제공하는 것이 사실 이 책을 읽는데 어렵게 하는 요소 중 하나였다.
순수 함수형 프로그래밍 언어라면 내가 알고 있는 것은 하스켈 밖에 없는데 (이마저도 들어만 봤을 뿐, 사용해 본 적은 없다) 스킴이라는 언어로 코드를 설명하면서 더 이해가 어려웠다.
반복문이 예약어로 내장되어 있지 않고, 반복을 실행할 땐 재귀를 사용한다.
(연산 속도를 포기하고 반복문을 쓰느냐, 메모리를 더 사용하고 재귀를 사용하느냐의 차이일 수 있겠지만, 재귀를 쓰면 코드를 더 간결하게 표현할 수 있다.)
책 자체가 MIT의 수업 자료로 활용되고 있는 자료다 보니, 연습문제가 너무 많아서 시간안에 다 풀어볼 수는 없었지만, 각 프로그래밍 언어별로 담긴 철학이나 구조를 이해하면서 프로젝트에 사용해야한다는 얘기들은 앞으로도 현업 개발을 하면서 많은 도움이 될 것이라는 것을 알고 있기에 스킴에 대해 당장 프로젝트를 하는 것은 아니더라도 언어 구조와 철학에 대해 추가적인 학습은 필요하다는 것을 느끼게 되었다.
4. 결국 코드를 짜는 것은 몇 번이고 동일한 기능을 다시 작업하는 일이다.
개인적으로 제일 와닿는 문구였고, 개발하는 것을 글 쓰는 것과 비유하는 것 같아 마음 깊이 새겨넣을 말이었다.
최근에 대규모 서비스를 지탱하는 기술이라는 책을 읽으면서 저자가 검색 엔진 개발할 때, 초기에는 단순하게 정규 표현식을 이용한 방법을 적용했지만, 사용자가 증가하면서 해당 코드의 성능만으로 감당할 수 없는 상황을 직면했다고 한다.
이를 타개하기 위해 Trie 알고리즘 등을 도입하는 것을 수행했는데, 결국 개발하는 것은 상황에 맞는 코드가 필요하기 마련이고, 개발자가 성장하면서 코드도 성장해 나가지 않나 생각하게 된다.
5. 약간은 아쉬운 번역체 표현들
아마 원문이 대학에서 활용되던 책이다보니, 생명공학, 수학, 천문학 등에 대한 표현이 많이 포함되면서 번역이 직역되는 것이 꽤 많이 보였는데 예를 들면 “승산적”이라는 표현 등이 보였다.
영문에선 multiplicative라고 해서 증가하는 것에 대한 표현인데, “승산적”이라는 표현을 네이버 국문 사전에 찾아보니, 곱셈의 예전 표현이라는 것을 알 수 있었다.
그리고 항수(arity)라는 표현을 책에서 찾아볼 수 있는데, 네이버 사전에는 해당 내용이 안나오고, 구글에서 검색해보니 다음과 같이 설명하고 있다.
컴퓨터 공학에서 Arity는 논리(logic), 수학(mathematics) 및 컴퓨터 과학(computer science)에서 함수(function) 또는 연산(operation)에 의해 취해지는 인수(arguments) 또는 피연산자(operand)의 숫자입니다.
쉽게 말해, 함수 인자(argument)로 인지해도 될 것 같은데 주석으로 추가 설명이 포함되었으면 좋았을텐데, 하는 아쉬움이 남았다.
3월에 읽었던 머신러닝 파워드 애플리케이션은 책이 빨리 읽혀서 리뷰 기간 내에 2번을 읽었지만, 이 책은
- 다양한 전공을 예시로한 설명
- 낯선 프로그래밍 언어
- 어려운 용어 표현
등으로 1회독을 간신히 했다.
개인적으로 언어 한 개 갓 배운 예비 개발자가 보려고 한다면, 조금 어려울 것 같다는 생각이 드는데, 읽으면서 조금 아쉬운 마음이 남는다.
다만, 주니어 개발자 이상의 사람들이라면, 결국 개발 철학과 설계에 대한 내용이므로, 한 번 읽어볼 가치는 충분히 있는 책이며, 여러 개발 상황에 있어 코드를 유연하게 작업하는 것에 대해 고민할 때, 찾게 되는 책일 것이라는 것을 확신할 수 있다.
5월에 읽게 될 책도 기대가 된다.