목록분류 전체보기 (518)
개발놀이터
이번 포스팅에선 제 프로젝트의 JWT 필터를 리팩토링 해보도록 하겠습니다. 우선 제 코드를 보여드릴텐데요. 정말 그지같지않을 수 없습니다. if else if else 몇번을 진행한건지 참... 한번 리팩토링 진행해보도록 하겠습니다. 클린 코드를 읽은 개념들을 바탕으로 리팩토링 해보겠습니다. public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { // 1. Request Header 에서 JWT 토큰 추출 String token = resolveToken((HttpServletRequest) request); Authenticati..
이번 포스팅에선 책 클린코드에서 나온 예제인 switch문을 인터페이스, 추상클래스로 리팩토링 하는 방법에 대해서 포스팅해보도록 하겠습니다. 사실 책에서는 두루뭉실하게 얘기하기 때문에 조금 와닿지 않아서 개인적으로 토이프로젝트를 한번 만들어 봤습니다. 추상클래스와 인터페이스는 최근에서야 온전히 이해하기 시작해서 조금 미숙할 수 있습니다. public Money calculatePay(Employee e) throws InvalidEmployeeType { switch (e.type) { case COMMISSTION -> { return calculateCommisstionPay(e); } case HOURLY -> { return calculateHourlyPay(e); } case SALARIED -..
이번 포스팅은 함수입니다. 우리는 개발할 때 수십개 수백개도 더 함수를 만들어냅니다. 정작 함수가 어떻게 읽기 좋게 쓰여지는지는 별로 고민하지 않는 제 모습을 봤습니다. 여기서 로버트 C.마틴의 말을 인용하면서 시작해보겠습니다. "함수를 만드는 첫번째 방법은 작게 만드는 것이다. 그리고 두번째 방법은 더 작게 만드는 것이다. 함수는 100줄을 넘어서는 안된다. 아니! 20줄도 넘어서는 안된다!" -로버트 C.마틴 함수 한 가지만 해라 함수 하나가 버퍼도 처리하고, 페이지도 가져오고, 상속된 페이지를 검색하고, 경로를 렌더링하고, 문자열을 덧붙이고, HTML 파일을 생성하는 만능 함수를 한번쯤 만들어보셨을겁니다. 이에 로버트 C.마틴은 "함수는 한 가지를 해야하고, 그 한가지를 잘해야하며, 그 한가지만을 ..
우리는 이름을 정말 많이 짓습니다. 클래스, 변수, 인터페이스, 추상 클래스, JAR파일, WAR파일 모두 이름을 붙이게 됩니다. 그러므로 이름을 잘 붙이는 것은 의미있습니다. 그리고 잘 못지은 이름은 가독성을 떨어뜨리기 마련이죠. 이번 포스팅에선 의미있게 이름을 붙이는 방법에 대해서 설명해보도록 하겠습니다. 의미있는 이름 의도를 분명히 밝혀라 우리는 가끔 변수명을 이렇게 짓곤 합니다. int d; 하지만 개발할 때 당시만 기억나고 한참 뒤에 이 변수를 보면 무슨 변수인지 헷갈릴 때가 많습니다. 그러므로 우리는 아래와 같이 바꿔야합니다. int daysSinceModification; 이에 조금 연장선상의 코드들을 한번 보시죠. public List getThem() { List list1 = new A..
로버트 C.마틴의 클린 코드를 읽었습니다. 책을 읽고 리팩토링의 중요성을 알게 되었고 제 코드에 녹여 내볼 생각입니다. 책을 읽으니 무지성으로 작성한 제 코드들이 눈앞에 휙휙 지나가더군요. 얼른 책을 다 읽고 리팩토링 해보고 싶습니다. 이 카테고리에선 리팩토링을 어떻게 진행해야 하는지 코드레벨에서 설명합니다. 출처는 클린 코드 저서구요. 리팩토링을 통해 얻을 수 있는 것들과 다양한 경험들을 소개해드리고자 합니다. 마지막으로 책의 첫부분을 인용하면서 리팩토링 카테고리 시작하도록 하겠습니다. "중복을 피하라, 한 기능만 수행하라, 제대로 표현하라, 작게 추상화 하라" -로버트 C.마틴
Q. 트랜잭션 전파단계에 대해서 설명해주세요 A. 스프링은 여러개의 트랜잭션 연산을 하나로 통합하기위해 물리 트랜잭션과 논리 트랜잭션이라는 개념을 도입했고 이로인해 트랜잭션 연산들이 전파되면서 원자성을 보장할 수 있었습니다. JPA에서는 다양한 트랜잭션 전파 단계를 지원하는데 디폴트값인 REQUIRED부터 무조건 새로운 트랜잭션을 만드는 REQUIRES_NEW 그외에도 SUPPORTS, NOT_SUPPORTED, NESTED, NEVER, MANDATORY 등이 있습니다.
Q. 왜 비관적 락을 사용했나요? A. 낙관적 락의 사용과 비관적 락의 사용 중 많은 고민이 있었습니다. 성능상 낙관적 락을 선택하고 싶었지만 이용자 수가 1000만명이나 된다는 컨셉 때문에 충돌이 빈번할 것으로 예측했습니다. 또한, 먼저 결제를 진행한 사용자에게 결제가 일어나고 그 뒤의 사용자는 결제가 일어나면 안된다는 생각 때문에 비관적 락을 선택했습니다.
Q. 왜 Redis를 사용하셨나요? A. 우선 대안책으로 EHcache와 Memcached가 있었습니다. 같은 글로벌 캐시인 Memcached는 Redis가 제공하는 다양한 자료구조와 장애가 발생해도 데이터를 유지할 수 있는 지속성, 수평적 확장이 용이하다는 특징 때문에 Redis를 선택했습니다. EHcache는 스프링과 통합이 쉽고 속도가 빠르다는 장점이 있어서 많은 고민이 있었지만 멀티 스레드 상황과 분산 시스템 상황에서 캐시 스토리지 동기화에 신경을 써야 해서 앞으로 분산 시스템으로 넘어갈 때 프로젝트의 복잡도를 올리고 싶지 않았습니다.
Q. 왜 JWT를 사용했는가? A. 우선 제 프로젝트의 종점이 MSA였다는 것을 먼저 피력하고 싶습니다. 때문에 격리된 애플리케이션 사이의 통신에서 인증을 위해 stateless한 인증 방식이 필요하다고 생각되었습니다. 기존 인증 방식은 스프링 시큐리티에 온전히 의존해 인증방식이 stateful하기 때문에 MSA와 맞지 않다고 생각했습니다.
Q. 왜 Jenkins를 사용했나요? A. 비교 대상은 Github Action이었고 많은 고민이 있었습니다. 결과적으로 Jenkins를 사용하게 된 이유는 우선 넓은 커뮤니티로 인해 풍부한 레퍼런스가 그 이유였습니다. 처음 CI 자동화를 하는 것이기 때문에 트러블 슈팅이라던가 레퍼런스를 참고할 곳이 많은 곳이 큰 메리트가 있었습니다. 또한 Github Action이 가지고 있는 문제 중 하나인 잡 스케쥴링에 종종 이슈가 있다는 것을 알고 CI 자동화 툴의 치명적인 단점이라고 생각했습니다.