Word Finder 개발기 1
어느 날 엄마가 일하는 모습을 보게되었다. 국어 학원 선생님이라 책에 나오는 어려운 단어를 아이들을 위해 검색하고 계셨다. 엄마는 그 많은 단어를 일일이 검색창에 치셔야 했다. 그것도 네이버 사전, 위키백과, 나무위키, 네이버 지식백과… 너무나 많은 검색을 하는 것이 보였다. 여기서 생각이 들었다.
만약 저 많은 사이트에 검색하는 과정을 자동화하여 한 번의 검색으로 여러 사이트의 결과를 얻을 수 있으면 더 편해지지 않을까?
그런 생각에 시작한 프로젝트가 바로 ‘Word Finder'이다. 가장 에센셜한 목표는 바로 검색 자동화와 그 결과를 한 화면에 모두 띄워주는 것이다. 결과론적으로 말하자면, 어느 정도 구조를 잡았다고 생각할 때 비로소 이 개발기를 시작하니 지금은 0.4.1 버전까지 나온 상태이다. 엄마도 이 프로그램을 유용하게 쓰시면서 수업준비를 하신다. 내 역량이 부족해 GUI 부분은 형편없기 그지 없지만 일단 그 외에는 나름 돌아간다고 생각한다.
가장 중요한 것
모든 프로젝트는 방향성이 가장 중요하다고 생각한다. 방향성은 프로젝트 자체의 퀄리티와 직접적으로 연관되어 있을 뿐만 아니라 프로젝트가 발전해 나가는 원동력이 되기 때문이다. 내가 지금 무엇을 위해 일을 하고 있는지 잊는다면 자연스레 능률도 떨어질 뿐만 아니라 쓸데없는 보여주기식 기능들이 추가되고 유지보수가 더 어려워질 뿐이다. 그래서 제일 먼저 프로그램의 목표부터 설정했다.
- 단어 검색
가장 중요한 기능이다. 단어의 입력과 결과의 출력이 어디로 나오던 그것은 세부사항일 뿐이다. 프로그램이 검색을 하지 못하면 당연하게도 단어 검색용으로 사용할 수 없다.
- 여러 검색 결과를 한 화면에 모두 보여주기
그저 한 페이지만 보여줄 수 있다면 네이버에 들어가서 검색하는 것과 다를 바 없을 뿐 아니라 오히려 이 프로그램을 쓸 이유가 없다. 여러 사전 사이트들에서 검색한 결과를 한 눈에 볼 수 있다는 것이 이 프로그램의 존재 이유이다.
프로그램의 설계에 있어서 처음부터 완벽한 그림을 그리는 것은 불가능할 뿐만 아니라 악영향을 끼치지만 적어도 가장 중요한 기능에 있어서는 제일 먼저 중심에 놓고 시작하고 싶었다. 그래서 네이버 사전과 위키백과 각각에서 단어를 검색해 받은 HTML 코드 중 필요하다고 생각되는 부분만 문자열로 반환하는 클래스 두 개를 만들었다.
로버트 마틴의 클린 아키텍쳐에 따르면 1번 기능을 구현한 모듈들은 프로젝트의 가장 안쪽에 위치해야 한다. 왜냐하면 일종의 정책이기 때문이다. 이것들은 입출력과 상관 없이 작동해야 하며 입출력의 존재조차 몰라야한다.
2번을 구현하는데 있어서 가장 큰 부분을 차지하는 것은 GUI이다. 그리고 입출력과 가장 가까운 것도 GUI 이기 때문에 2번을 구현하는 모듈은 가장 바깥쪽에 위치해야 한다. GUI는 굉장히 변화하기 쉽고 또 그럴 것이기 때문에 1번과 같은 기능들에 영향이 가지 않도록 격리할 필요가 있다.
GUI 프로그래밍이 이번이 두 번째고 아직 제대로 된 개념조차 못 잡은 상태였기 때문에 이 부분에 있어서 많은 어려움이 있었다. GUI를 바깥으로 빼내는 작업부터 GUI 자체를 구현하는 일까지 솔직히 깔끔하게 한 것이 더 적다고 생각한다.
그래도 중요한 것
이 프로젝트는 엄마를 위한 것이기도 하지만 내 공부를 위한 것이기도 하다. 예전부터 의미있는 일을 하는 프로그램을 만들고 싶었다. 구구단이나 계산기, 기껏해야 왜 있는지도 모를 데이터들을 빠르게 정렬하는 프로그램들을 만들었다. 물론 그 과정이 굉장히 중요하고 의미있으며 나를 성장시켰다는 것에 전적으로 동의한다. 그래도 내게 무언가 도움이 되는 ‘자비스' 같은 프로그램들을 꿈꾸기 마련 아닌가?
내가 말하고 싶은 것은 내가 공부하며 알아가는 만큼 이 프로젝트도 변한다는 것이다. 현재는 두 개 밖에 없는 결과 창이 나중에 네 개가 될 것이고, 더 많은 기능들이 추가될 수 있다. 동시에 이 프로그램은 실 사용자가 존재하고(단 한명 뿐이지만 충분히 의미있다), 사용자에게 이 변화가 적용될 수 있어야 한다. 다시 말해, 업데이트 기능이 있어야 한다.
업데이트는 수정된 프로그램을 사용자가 다운받아 설치하는 과정을 자동화시킨 것이라고 생각한다. 귀찮게 깃헙 사이트에 들어가서 릴리즈 버전을 다운 받는 수고를 들이지 않고 프로그램 내에서 쉽게 업데이트할 수 있도록 구현하고자 하였다.
모델
사람이 살면서 어느 한 순간은 누군가를 닮고 싶기 마련이다. 나도 내 프로젝트가 닮았으면 하는 프로그램이 있었다. 개발자께서 원하지 않아 무엇인지는 밝히지 않지만, 1인 개발에 소스코드를 모두 깃헙에 올려두지 않은 프로그램이었다. 파이썬으로 구현되어있으며 PyQt5를 사용한 GUI라는 정보 외에는 딱히 알 수 있는 것이 없었다. 직접 개발자 본인에게 문의해 소스코드를 받을 수 있었다. 커밋관리나 문서를 정리하기 귀찮아서 올려놓지 않았다고 하셨다.
소스를 받아본 나는 깜짝 놀랐다. 아무리 단 한 사람의 메인테이너 밖에 없다고 하지만 단 한줄의 주석조차 볼 수 없었다. 코어 모듈들은 단 한 개의 패키지에도 들어가있지 않았고 그 의존성도 파악하기 너무나 어려웠다. 한 모듈이 여러 곳에 쓰이면서도 어떤 수준을 갖고 존재하는지 알 수 없었다. 플래그 변수명은 ‘res', ‘d', ‘r' 등이어서 도대체 무슨 값을 나타내는 플래그인지 알아내려면 함수 원형을 찾아가야 했다. 어떤 파일은 IDE가 차마 분석할 수 없을 만큼 길면서도 그 안에 서로 다른 일들을 하는 클래스들이 여럿 들어가 있었다. 대단히 분석하기 어려웠다.
몇 가지 건진 것들이 있는데 나중에 풀어보도록 하겠다.
구조
하여간 나는 더 친절하고 유지보수하기 쉬운 코드를 쓰고 싶었다. 그게 나에게 더 편한 길임과 동시에 옳은 길이기 때문이다. 간단한 프로그램이지만 모듈들을 최대한 기능에 따라 분리하고 입출력에 더 가까운 모듈이 그렇지 않은 모듈을 참조하고 반대의 경우는 발생하지 않도록 하였다. 이에 대한 자세한 내용은 나중에 다루어볼 예정이다.
마무리
비록 많이 부족한 실력이지만 그동안 배운 것들과 지금 배우고 있는 것들을 직접 사용해보고 구체화하는 과정에서 공고히 할 수 있었다. 생전 관심 없었던 PyQt5도 외국 원서까지 구매해 봐가면서 익혀야 했고 반응성 개선을 위해 멀티스레딩도 머리 싸매며 공부했다. 내가 워낙 모자라서 그런지 몰라도 정말 많이 배울 수 있었던 프로젝트였다.