두 번째 수업 이모저모

  • 수업은 2017-04-06 19:00:00 +0900에 시작.
    • 오늘부터 다음 주 목요일 2017-04-13 까지는 HTTP Web Server 개발 실습을 한다.
    • 그 다음주 월요일인 2017-04-17 에는 교수님의 라이브 코딩이 예정되어 있다.
  • 단상 : 프로그래밍 연습 어떻게 할 것인가?
    • 작은 프로그램을 반복적으로, 다양하게 구현해 보도록 한다.
  • 교수님 라이브 코딩 및 TDD 시범.

  • TDD 실천법에 대한 논의 및 Q & A.
    • TDD 경험에 대한 발표.
    • TDD를 하려면 객체지향 철학을 잘 활용해야 한다.
    • 로직 위주로 가도록 한다.
    • 과도한 테스트 코드는 지양한다.
  • 마틴 파울러와 직원들이 지은 책 The ThoughtWorks Anthology에 나온 객체지향 생활 체조 소개.
    • 좋아하는 책이었기에 반가웠다.
    • 집에 돌아와 객체지향 생활 체조 챕터를 다시 읽어 보았다.

객체지향 생활 체조

  1. 한 메서드에 오직 한 단계의 들여쓰기만 한다.
  2. else 예약어keyword를 쓰지 않는다.
  3. 모든 원시값과 문자열을 포장wrap한다.
  4. 한 줄에 점을 하나만 찍는다.
  5. 줄여쓰지 않는다(축약금지).
  6. 모든 엔티티entity를 작게 유지한다.
  7. 2개 이상의 인스턴스 변수를 가진 클래스를 쓰지 않는다.
  8. 제일 클래스first-class 콜렉션을 쓴다.
  9. 게터getter/세터setter/프로퍼티property를 쓰지 않는다.

꽤 깐깐한 체조 같지만, 조금만 생각해보면 개발자의 멍청한 실수를 최대한 예방하는 좋은 습관들임을 알 수 있다.

문득 스티브 맥코넬이 Code Complete 에서 한 말이 생각났다.

최종 목표는 한번에 생각해야 하는 프로그램의 양을 최소화하는 것이다.

for 루프를 쪼개야 할까

Q & A 시간에 for loop에 대한 이야기가 나왔다.

두 가지 일을 하는 하나의 for loop를 교수님이 한 가지 일을 하는 두 개의 for루프로 쪼갰는데 누군가 이런 말을 했다.

"for 루프가 두 번 돌아서 기분이 나쁩니다."

지극히 정상적이고 상식적인 반응이다. 그러나 이것은 반론 불가능한 도그마일까? 복잡한 for 루프는 버그의 온상이다. 새벽 두 시에 끝이 안 보이는 for 루프를 투덜대며 분해해 본 경험을 누구나 갖고 있지 않나? 나는 약 3년 전, Scala를 사용하기 시작했을 무렵부터 루프를 쪼개는 습관을 갖게 되었는데 나 뿐만 아니라 주위의 동료들이 (아주 미묘한 차이이긴 하지만) 조금씩 더 행복해진 놀라운 경험이 있다.

찾아보니 이 건에 대해서도 스티브 맥코넬이 Code Complete 에 남겨 놓은 말이 있다.

루프가 한번에 두 가지 일을 하기 위해서 사용될 수 있다는 사실만으로는 두 가지 기능을 동시에 수행해도 된다는 것을 정당화하지 못한다. 하나의 루프는 반드시 한 가지 일만 수행하고 그 작업을 제대로 수행해야 한다는 면에서, 루틴과 같아야 한다. 만약 루프 하나만으로도 충분한 코드에 두 개의 루프를 사용하는 것이 비효율적인 것처럼 보인다면, 두 개의 루프로 코드를 작성한 후, 효율성을 위해서 결합될 수 있다는 것을 주석으로 작성하여, 두 개의 루프를 하나로 통합하기 전에 벤치마크 결과가 해당 코드 섹션에서 성능 문제가 발생한다는 것을 보고할 때까지 기다리도록 한다.

생각해 볼 것들.

  • O(2n)O(n)의 관계.
  • 런타임 시간보다 개발/유지보수 시간을 중요하시는 관점.
    • 산업의 유형에 따라 선호하는 언어가 다른 이유하고도 관련이 있다.

코딩 실습 및 과제 : HTTP 웹 서버 구현

  • 이 작업은 박재성 교수님의 web-application-server를 fork하여 수행하도록 한다.
  • 다음 시간까지 최소한 요구사항 5 까지는 작업해 올 것.

요구사항

  • 요구사항 1 : 웹서버 구색 갖추기
    • http://localhost:8080/index.html 로 접속했을 때 webapp 디렉토리의 index.html 파일을 읽어 클라이언트에 응답한다.
  • 요구사항 2 : 회원가입 구현.
  • 요구사항 3 : 회원가입 구현기능을 post 방식으로 변경하기.
  • 요구사항 4 : 회원 가입을 완료하면 /index.html로 이동하게 한다.
  • 요구사항 5 : 로그인 구현, 로그인 성공/실패시 페이지 리다이렉트.
  • 요구사항 6 : 로그인 상태에서 /user/list로 접근하면 사용자 목록 출력.
  • 요구사항 7 : css 지원.

과제 후기

  • 만들다보니 Annotation 기반의 Controller Interface 형태의 웹 서버를 구현하게 되었다.
  • 평소 Annotation을 자바 진영의 일종의 흑마술 이라고 생각해서 별로 좋아하지 않았는데, 직접 뭔가 만드는 데 사용해보니 엄청 편리하다. Annotation에 대한 호의가 무럭무럭.
  • 나는 immutable 개념을 좋아해서 가능한 한 변수는 사용하지 않고 final 상수를 사용하며, 중요 MapListunmodifiable을 씌워줬다. Java 문법상 꼭 키워드를 하나씩 더 타이핑해야 해서 너무 귀찮았다. Java의 문법은 내 언어 습관상으로는 몹시 수다스럽다. Vim이 아니라 IntelliJ의 조악한 Vim 플러그인으로 코딩을 했더니 손가락이 얼얼하다.

  • 내 구현 내용은 Github repository에 올려두었다.
    • RequestHandler : 이거 리팩토링하느라 걸린 시간이 전체 개발 시간의 80% 는 되는 것 같다.
    • UserLogin 클래스 : Spring 처럼 Controller 어노테이션을 만들어 적용해 보았다. 재밌었다.

Links