회고

오늘은 ArrayParser를 구현하는 미션이었다. Object를 만들기 위해, 입력받은 문자열을 Tokenizer, Lexer, Parser 과정으로 처리해야 하는 것이었다. Java의 Jackson 같은 파싱 라이브러리는 사용해보았지만, 직접 구현하려다 보니 막막했다. 우선 Tokenizer, Lexer, Parser이 구체적으로 무엇을 의미하고 어떤 역할을 해야하는지 궁금하였다.

  • Tokenizer는 문자열을 작은 단위의 Token으로 나눠서 토큰화하는 과정이다.
  • Lexer는 각 Token의 어휘를 분석해서 의미를 부여한다.
  • Parser는 각 Token의 문법을 체크하며 구조화된 데이터로 변형시킨다.

이번 미션에서 Lexer 과정에서 각 토큰을 Node로 만들어 Tree로 구조화하도록 설계하였다. 이번 미션에서 개인적인 목표는 함수를 작은 단위로 나누고, 각 Tokenizer, Lexer, Parser, Node(Token 이라는 객체명이 더 적합한 것으로 보인다...) 객체 자신의 책임에 맞게 메시지를 제공하여 코드 중복을 제거하고자 하였다. Lexer에서 각 토큰이 Number, String, Null, Array 타입에 따라 다른 로직으로 의미 부여를 하고자한 것은 괜찮았지만, Tokenizer 객체에서 문자열을 제대로 토큰화하지 못하며, Tokenizer 객체의 책임을 Lexer 객체에서 처리하였다. 결과적으로 Tokenizer 객체는 자신의 책임을 다하지 못하게 구현이 되어 버렸고, Lexer 객체는 단일 책임 원칙을 지키지 못하였다.

개선 방법

Tokenizer 객체는 단순히 문자열을 자르는 것만이 아닌, Token으로 구체적인 자료구조(ex> Array, Tree, ...)로 구조화해야 하는 책임이 있다. 따라서, 각 Token으로 Tree를 만드는 로직은 Lexer가 아닌 Tokenizer 객체에서 처리되어야 한다. Lexer는 제공된 Tree를 순회하며 각 Token(Node)의 어휘를 분석하고 의미 부여에 대한 책임만 가지기 때문에, 단일 책임 원칙을 지킬 수 있게 될 것이다.