클린코더스, Architecture

좋은 Architecture는 tool로부터 decouple해야 한다.

  • 대체로 아키텍쳐라고 하면 보통 언어(java), 프레임워크(스프링), DB(Mysql), sql mapper(jpa hibernate) 등을 의미하며, 개발 이전의 설계나 기획이라고 생각하는 경향이 크다.
  • 오히려 좋은 아키텍쳐는 위에 나열한 툴과 기획에 의존하지 않는 상태에서 만들어진다. tool에 한정되는 순간 툴에 종속적인 유연하지 않은 어플리케이션이 된다.
  • tool로부터 decouple하고 최대한 그 선택을 늦춰야(Deferring decisions) 한다.
  • 현대적 의미에서 아키텍쳐는 use case로 설명한다. 어플리케이션의 actor를 상정하고, 사용자가 어플리케이션을 사용하고 상호작용하는 것에 초점을 맞춘다.

Deferring Decisions 툴에 대한 결정을 최대한 미룬다

  • 좋은 아키텍쳐는 툴에 대한 결정을 최대한 연기한다.
  • 우리는 충분한 정보를 가지고 있지 않다. 우리가 가진 정보는 언제든 변경될 수 있다. 우리에게 요구한 사람들은 자신이 무엇을 요구하는지도 명확하게 모른다.
  • “known unknowns” 혹은 “known knowns” 보다 “unknown unknowns” 인 경우가 많다. 그러니까 우리는 기획, 설계 때 상황에 따라 무엇이 적절한 도구 혹은 디자인 패턴인지 알지 못하는 경우가 많다.
  • 개발은 그러므로 툴에 대한 선택을 최대한 늦추는 방향을 선택해야 한다. DB를 예를 들면 아래와 같다.

DB is core abstraction?

  • 보통 개발은 DB 중심으로 수행하기 십상이다. 그럼 시스템은 DB에 종속적인 형태로 개발된다. sql 중심으로 개발하면 절차지향적인 개발이 될 가능성이 매우 높다.
  • undo의 비용은 생각보다 크다. Mysql에서 postgreSQL로 변경하는 것은 쉽지 않다. db를 선택하는 것을 최대한 늦추는 것이 장기적으로 낫다.
  • DB를 대신하는, 결정을 최대한 늦추는 개발은 다양하며, 그 방식은 좋은 아키텍쳐를 만드는데 도움을 준다.
    • 대역(double) repository를 사용한다. 일단 가짜 클래스에 save() 메서드를 구현한다.
    • 데이터를 불가피하게 넣어야 한다면 Map을 사용한다.
    • 데이터가 휘발되어선 안된다면, 메모리를 직렬화하여 파일로 저장한다.
    • sql의 사용을 회피할 수 없다면 인메모리 DB를 사용한다.
    • 개발이 거진 완료되고 데이터를 영속화해야 하는 상황이 도래할 때, DB를 선택한다.

빠른 구현과 리팩터링(혹은 재개발)은 현대적인 개발에서 필수이다.

  • 유사한 어플리케이션이 나오는 상태에서 빠른 개발은 필수이다.
  • 경쟁사보다 먼저 시장을 선점하기 위해서는 좋은 기획에 초점을 맞출 수 없다. 급박하고 급변하는 상태에서 완벽한 기획과 설계를 하고 개발하는 것은 어렵다. 일단 동작하되 더럽게 만든다.
  • 사족으로, 만약 어플리케이션이 시장에서 호응이 좋고 동작도 잘 할 경우, 우리에게는 두 가지의 선택지가 남겨진다.
    • 1) 고객의 요구사항에 따라 새로운 기능을 추가한다. 하지만 급하게 만든 코드는 더러워지고 문제가 방치된다. 역겨운 코드가 된다.
    • 2) 어플리케이션이 동작하면 이를 리팩토링한다. 혹은 이전의 경험을 기반으로 새롭게 만드는 것이 더 나은 선택일 수 있다. 무엇이 되었든 이때 좋은 디자인의 코드를 구현하기 위해 노력한다. 유연하고 좋은 코드가 작성되면, 이때부터 새로운 기능을 추가한다. 이때 TDD 기반으로 개발하고 회귀 테스트가 완비될 경우 리팩터링에 자신감을 가지고 수행 가능하다.
  • 빠르게 배포를 하기 위하여 만들었던 코드는 재사용해야 하는가? 그것을 다시 구현하고 테스트코드를 작성하는 일은 새로 만드는 일보다 오래 걸린다. 어플리케이션은 빠르게 출시하고 그 이후에 그것을 더 단단한 형태로 새로 개발하는 것이 맞다.

MVC의 오용

  • MVC란 model, view, controller 가 각각의 레이어로서 독립적으로 존재하는 디자인 패턴이다. 그러니까 model 시스템을 보면, 그것이 web인지 모바일 앱인지 알 수 없어야 한다.
  • 하지만 대체로 MVC 패턴은, model이 view나 controller에 강하게 의존하는 경향이 있다. 그러니까 model에서 view에서 사용하는 html 관련한 데이터가, controller의 session이나 request/response 객체가 침투한다. model이 pojo하지 못한다. model이 pojo하면, controller와 model 사이에 pojo하지 않은 레이어가 하나 더 있는 경우도 있다.
  • architecture 변경 없이 delivery 메커니즘을 변경할 수 있어야 한다.

boundary object, partitioning

  • 각 영역을 분리한다. 각 영역은 interface로 적절하게 연결한다. 연결을 할 때 Data structure로서 dto를 사용한다.
  • web에서 request은 일종의 Data structure이다.

use case

  • Use Case는 입력 데이터를 해석하여 출력 데이터를 생성하는 필수 알고리즘. 시스템의 상호작용과 시스템의 의도를 보여준다.
  • “사용자가 무엇을 한다 -> 시스테임이 어떻게 대응한다”의 핑퐁 스타일이다.
    • 이를 문서로 정리할 때, “사용자가 무엇을 한다” 수준으로 간략하게 정리할 수도 있다. 에러 상황에 대한 복잡한 내용까지 정리할 수도 있다. 형식이 정해져 있는 것은 아니다.

architect?

  • 회사는 아키텍트을 시니어 개발자가 되기를 바란다. 기획, 설계, 디자인, 리뷰 등을 하기 바란다. 코딩은 저급한 것으로 보곤 한다.
  • 하지만 코드를 작성하지 않으면 개발자는 무능해진다.
  • 기획, 설계는 계속 변경된다. 소스코드가 기획, 설계도가 된다. 소스코드를 잘 작성하는 것이 아키텍트의 역할이다.