현재 진행 중인 프로젝트에서, 도메인 객체가 시간 값을 초 단위의 타임스탬프 타입으로 가지도록 약속되었다. 정확히는 유닉스 타임스탬프로 시간 값을 가진다. UTC를 기준으로 1970년 1월 1일 00시 00분 00초부터 경과된 초를 말한다. 개발 중인 서비스가 국가 별로 다른 시간대를 나타내는, 그러나 서버 어플리케이션은 한국 시간대로 설정된, 상황이기 때문에 LocalDateTime과 같은 시간 객체로는 개발에 혼동이 올 수 있고, 운영 중에 문제가 발생해도 바로 대응하기가 힘들기에 타임스탬프로 통일하자는 의견이었다. DB 레이어와 Controller 레이어에서는 LocalDateTime을, Domain 레이어에서는 LocalDateTime을 사용했다. 그래서 상호 간에 변환하는 기능이 필요했는데, 이..
Ruby는 인터프리터 언어이고, 타입이 느슨하기 때문에 높은 생산성을 자랑한다. 하지만 타입이 느슨한만큼, 코드 컨벤션 체계가 확실히 잡혀있지 않으면 치명적인 실수를 일으킬 수 있다. 변수에 어떤 타입이든 담을 수 있기 때문에 변수가 String임을 기대하고 있는데 다른 타입이 들어와 버그가 발생하는, 예측하기 어려운 상황이 발생한다. 내가 몸 담고 있는 팀 또한 Ruby On Rails를 일부 프로젝트에서 사용하고 있다. 방대한 레거시 코드, 부족한 개발 기간, 코드 컨벤션 체계의 부재 등 실수를 유발할 수 있는 다양한 요인이 존재한다. 그래서 가끔 크고 작은 버그가 발생한다. 이를 방지하기 위해 데이터 타입을 강제할 수 있는 방법이 필요했다. 몇 달 전, 처음으로 적용했던 건 키워드 인자이다. 이는 ..
최근 Spring Boot 프로젝트의 테스트 코드를 작성하면서 동료에게 배웠던, 유용한 요령들에 대해 정리해보고자 한다. 코드의 기술 스택은 다음과 같다. Spring Boot 3.2.4 JDK 17 Kotlin 테스트를 위한 fixture를 간단히 생성하기 테스트 코드를 작성하다보면, 객체를 생성하는 데 번거로움이 있다. 필드가 많은 객체라면… 테스트 코드 작성하는 게 영 귀찮을 것이다. 이를 해결해줄 수 있는 여러 라이브러리가 있는데, 개인적으로 간편해서 주로 사용하는 라이브러리와 사용법에 대해 간단히 소개하겠다. fixture라는 라이브러리인데, 아래처럼 의존성을 추가한다. testImplementation("com.appmattus.fixture:fixture:{version}") private ..
최근 회사에서 새로운 프로젝트를 준비하고 있다. 당시 다른 업무를 맡았기에, 프로젝트 방향성을 듣지 못했다. 그래서 여차 방향성이 결정된 후에 어떻게 진행할지 들을 수 있었다. 제목에서 유추할 수 있듯이, 서버는 헥사고날 아키텍처를 중심으로 설계된다. 헥사고날이라는 용어를 생전 처음 듣기에, 당일 저녁 퇴근 직후에 여러 자료를 조사해봤다. 꽤 흥미로웠다. 스프링 부트에서 주로 많이 사용했던 레이어드 아키텍처의 단점인, 각 레이어간의 결합도가 높은 문제를 해결할 수 있고, 새 프로젝트가 요구 사항이 빈번하게 바뀔 수 있는 도메인이라는 점을 고려했을 때 적합한 설계라고 보여졌다. 여기까지가 헥사고날을 왜 학습했는지에 대한 이야기이다. 각설하고, 지금까지의 스프링 부트 프로젝트에서 레이어드 아키텍처만 사용했기..
개요Spring은 동시에 여러 요청을 처리할 수 있다. Spring Web을 사용한다면, 요청 하나 당 하나의 스레드가 할당되어 작업을 처리한다. 일반적으로 @Controller 및 @Service를 통해 REST API를 구현하는데, 이는 대개 Singleton Scope로 생성하여 관리한다. 어떻게 Spring은 Singleton Scope로 생성한 Bean을 여러 스레드가 접근하여 작업할 수 있는지 정리해본다. 동시에 같은 Bean에 접근?Spring Bean은 Heap Memory에 저장되기 때문에, 어느 스레드에서든 접근이 가능하다. @Service class UserService { private val players = listOf( Player("Kevin De Bruyne"), Playe..
“ARS 전화가 오지 않아 가입이 불가하다는 문의가 계속 오고 있습니다.” 아침에 출근했을 때, CS 팀으로부터 연락이 왔다. 서비스 가입 과정에서 ARS 인증을 요구하는 단계가 있는데, ARS 전화가 오지 않는다고 했다. 서버 배포가 없었다면 ARS 서비스를 제공하는 외부 업체가 불안정하여 문제가 된다고 판단했을 것이다. 하지만 전 날에 서버 배포가 있었고, ARS 인증 API에 수정이 있었다. 사건의 발단서비스는 오직 ARS 인증만을 지원했다. ARS API는 동기식으로 동작했다. 흐름은 이랬다. 앱이 서버로 ARS를 요청한다. 서버는 외부 업체로 ARS 인증을 요청한다. 전화를 받고, 인증을 진행한다. 인증이 완료되면, 전화를 종료한다. 외부 업체는 인증 결과를 서버로 응답한다. 서버는 인증 결과를..
푸시 발송 서버를 만들 때, StringBuilder를 사용하여 문자열의 내용을 치환하는 기능을 구현한 적이 있었다. Java나 Kotlin의 String 클래스는 불변이기 때문에, 문자열을 수정할 때마다 새로운 문자열 객체를 생성한다. 그래서 메모리를 많이 사용하는 문제가 있다. 반면 StringBuilder는 문자열을 수정해도 기존의 객체를 계속 사용한다. toString() 메소드를 호출하면 그제야 String 객체를 반환한다. 그래서 수정하는 데 메모리 부담이 없다. 그렇다면 어떠한 원리로 StringBuilder는 새로운 객체의 생성 없이, 문자열 데이터를 수정할 수 있는지 살펴보자. StringBuilder의 동작 원리 먼저 문자열의 뒤에 새로운 문자열 데이터를 덧붙이는 append를 살펴보면..
캡슐화를 활용하면 소프트웨어 개발 분야에서 쉽게 찾아볼 수 있는 상태와 복잡도의 증가에 순응할 수 있다. 상태를 내면화해서 다른 컴포넌트로부터 숨기며, 안전하게 디자인된 API로만 상태를 변경할 수 있게 하는 것이 캡슐화의 기본 개념이자 복잡한 정보 시스템을 디자인하고 구현하는 핵심이다.1 캡슐화는 다른 객체와의 메시지를 위해 공개할 것들만 공개하고, 나머지는 모두 숨기는 것을 의미한다. 즉, 외부 객체가 필요로 하지 않는 사항은 공개할 필요가 없다. 내부 구현을 변경하여도, 외부 공개 인터페이스를 변경하지 않으면 호환성이 유지된다. 외부에서 객체의 속성에 접근하는 불상사를 막을 수 있다. Java의 경우, getter와 setter를 사용하여 객체의 상태를 얻고, 설정한다. 이때 setter를 남용하면..
- Total
- Today
- Yesterday
- 디자인패턴
- 개발
- 실수방지
- 테스트코드
- java
- 책
- 몽키패치
- Bean
- 생각
- 레거시코드
- rubyonrails
- OOP
- 스프링부트
- 멀티스레딩
- 레디스
- 리팩터링
- 일상
- AWS
- 회고
- springboot
- 스레드
- 몽고
- Spring
- RUBY
- 코틀린
- 도서
- kotlin
- 루비
- 테스트
- 헥사고날
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | |
7 | 8 | 9 | 10 | 11 | 12 | 13 |
14 | 15 | 16 | 17 | 18 | 19 | 20 |
21 | 22 | 23 | 24 | 25 | 26 | 27 |
28 | 29 | 30 | 31 |