☄️ 경계도 설계다 – 내 프로젝트에서 수립한 경계 처리경계, 즉 내 코드와 외부 코드(서드파티 라이브러리, 오픈소스, 타 시스템) 사이의 접점은 생각보다 많은 위험을 내포하고 있었습니다.그동안은 RedisTemplate, RestTemplate, Logger, 외부 API, Map 같은 것들을 아무 생각 없이 바로 사용하는 경우가 많았죠.하지만 이 장을 읽고 난 후, 저는 다음과 같은 목표를 세웠습니다.✔️ 외부 시스템과의 접점을 깔끔하게 감싸고✔️ 그 변경에 우리 시스템이 휘둘리지 않도록 보호하고✔️ 테스트 가능한 단위로 쪼개기 서드파티 라이브러리나 외부 API (Map, log4j, 결제 모듈) 등은 직접 사용하면 변경에 취약해지고 테스트도 어렵습니다.그래서 저는 다음과 같은 리팩토링을 적용했습니다..
전체 글
타임딜 프로젝트에서 배운 Spring 예외 처리 리팩토링 실전 안녕하세요!커머스 프로젝트를 개발하며 점점 복잡해지는 예외 처리 로직을 개선하고, 클린 코드 원칙을 적용한 리팩토링 경험을 정리해 보았습니다. 이번 글에서는 단순히 try-catch를 줄이는 수준이 아니라, 실제 실무에서 적용 가능한 예외 처리 전략과 리팩토링 전후 코드의 차이점까지 소개해볼게요! 코드 예제는 제가 실제로 리팩토링 하며 사용한 코드들을 가져와 설명해 보도록하겠습니다~.또한 내용정리에 들어가기에 앞서, 먼저 이 글의핵심...제가 이글을 읽고 설계한 예외처리 전략을 우선 소개해보려합니다. ☄️ 예외도 설계다 – 내 프로젝트에서 수립한 예외 처리 전략 예외 처리... 사실 다들 하긴 하는데,"어떻게 해야 잘했다 소리 듣지?" 이 질..
안녕하세요!Spring Boot 기반 API를 개발하고 있는 쩡이입니다.오늘은 제가 실제로 고민한 Spring API 예외 처리 구조 리팩토링 경험을 공유해보려고 해요.강의 자료와 클린 코드 책을 바탕으로 더 스프링답고 유지보수 쉬운 구조로 개선해보았습니다. 😊 이번 글에서는 Spring 예외 처리의 기초 개념과 전역 처리 구조에 대해 설명합니다. 클린 코드 관점에서 이를 어떻게 리팩토링했는지는 다음 포스트에서 이어서 다룰 예정입니다! :)📘 Part 1. 서블릿 기반 예외 처리와 오류 페이지스프링은 기본적으로 서블릿 스펙을 기반으로 예외를 처리합니다.처음엔 아래 두 방식으로 예외를 던질 수 있죠.throw new RuntimeException("에러!");response.sendError(500, ..
오늘 공부해볼 내용은 '형식 맞추기' 챕터이다. 이글을 읽고 느낀점은 다음과 같다. 첫째, 코드 형식이 단순한 ‘꾸밈’이 아니라 의사소통 수단이라는 점이 인상 깊다. 빈 행 하나, 공백 하나에도 “이건 한 덩어리 개념이야” 혹은 “이 부분은 밀접하게 엮여 있어”라는 메시지를 담을 수 있다는 생각이 신기하다. 덕분에 무심코 지나쳤던 줄바꿈의 의미를 곱씹어 보게 되었고, 앞으로 코드를 쓸 때마다 ‘내가 동료에게 어떤 생각을 전하려 하나?’를 먼저 떠올리게 될 것 같다.둘째, 밀집도와 코드 간 거리를 적절히 조절하면 코드가 눈에 들어오는 방식이 달라진다는 사실을 이 글로 재확인했다. 예전 프로젝트를 할때 이 부분들이 늘 헷갈리고 고민됐는데, 앞으로 “사용 위치 바로 앞에 변수 선언하기”나 “종속 함수는 호출하..

오늘은 주석을 다뤄본다. 클린 코드 내용을 정리하고, 이를 바탕으로 내 프로젝트를 리팩토링해보겠다. 🧭 목차주석은 나쁜 코드를 보완하지 못한다코드로 의도를 표현하라좋은 주석 vs 나쁜 주석반드시 피해야 할 주석 유형마무리 체크리스트❌ 1. 주석은 나쁜 코드를 보완하지 못한다주석은 종종 지저분한 코드를 해명하려는 변명일 뿐이다.코드 자체를 더 명확하게 리팩터링하는 것이 우선이다.Bad// 직원에게 복지 혜택을 받을 자격이 있는지 검사한다if ((employee.flags & HOURLY_FLAG) && (employee.age > 65))Good if (employee.isEligibleForFullBenefits())✅ 2. 코드로 의도를 표현하라변수명, 함수명, 모듈구조로 충분히 의도를 드러낼 수 있..

오늘 공부해볼 내용은 함수 챕터이다. 클린 코드 책을 바탕으로 내 코드를 리팩토링 해 보겠다. 리팩토링 전 코드변명이지만 일단 기능 구현에 초점을 맞추고 추후 리팩토링을 고려해...일부러 이렇게 막막히 작성한것도있다.@Service@Transactional@RequiredArgsConstructorpublic class ReviewService { private final ReviewRepository reviewRepository; private final TimeDealRepository timeDealRepository; private final PurchaseRepository purchaseRepository; private final UserRepository userR..

문제 설명두 개의 랜덤 문자열 s, t가 주어진다. 이때, 한 문자열 또는 양쪽 문자열에서 총 최대 2글자를 삭제하여 두 문자열이 완전히 동일해질 수 있는지 판단하는 문제이다.삭제 연산만 허용하며, 삽입이나 교체는 불가능.삭제 횟수의 합이 2를 넘으면 안 된다.s = "abcde"t = "ade"# "abcde"에서 'b','c'를 삭제하면 "ade"가 되어 같아지므로 True.해결 아이디어길이 차이 배제: |len(s) - len(t)| > 2라면 최대 2회 삭제로 같아질 수 없으므로 곧바로 False.투 포인터 + 재귀 백트래킹:두 문자열을 각각 포인터 i, j로 순회.남은 삭제 예산 rem을 함께 관리.문자가 같으면 (i+1, j+1, rem)으로 진행.다르면 두 가지 선택지:s[i] 삭제 → (i..

문제 배경격자(그리드) 형태의 보드 위에서 특정한 “격자점(grid point)”을 중심으로 대각선이 수평·수직 방향에 45°로 기울어진 마름모(다이아몬드) 모양을 정의하고, 각 셀(cell)이 이 마름모에 완전 포함되는지, 일부만 겹치는지, 전혀 겹치지 않는지를 판정하는 문제. Pythonimport sysinput = sys.stdin.readline# 입력 예시# 4# 5 7 8 2# 3 6 9 4# 8 1 2 3# 4 5 7 6# 1 2 4def mark_diamond(board, center, r): n = len(board) cx, cy = center d = r / 2.0 # 결과 마스크 초기화 mask = [[0] * n for _ in range(n)] ..

https://www.acmicpc.net/problem/1655 매번 정렬은 너무 느리다“새로운 수가 들어올 때마다 지금까지의 리스트를 정렬한 후 중간값을 꺼내자”→ 한 번 정렬에 O(N log N), 전체 N번이면 O(N² log N)… N=10만에 절대 안 된다.중간값만 빠르게 뽑을 수는 없을까?우리가 필요한 건 전체를 정렬된 상태로 유지할 필요 없이 “지금 중간값이 뭐냐?”만 알면 된다.삽입과 중간값 조회를 모두 O(log N) 안에 해결할 수 있는 자료구조를 찾아보자.한쪽 힙만으로는 부족하다최소 힙(min-heap)이나 최대 힙(max-heap) 하나만 있으면,삽입은 O(log N) OK그러나 중간값(“k번째 원소”) 조회는 지원하지 않는다.작은 절반 vs 큰 절반, 두 개의 힙!작은 절반은 ..
비밀 코드 해독을 풀어봤다.너무풀고싶게생김..ㅋ_ㅋ이 문제힌트는 범위 제한이다. 범위가 10,30이므로 적으므로.가자 브루투포스! 자바로도 풀어보고 느낀점: 모듈로 퉁치면되니까 파이썬 사기네;자바는 얼른 조합라이브러리를 내놔라.. Pythonfrom itertools import combinationsdef solution(n, q, ans): answer = 0 guess_sets = [set(guess) for guess in q] count = 0 for comb in combinations(range(1, n + 1),5): is_valid = True # 이 조합이 모든 시도 조건을 만족하는지 for i, guess_..