_

Always be tactful

분류 전체보기 93

비즈니스 로직이니까 서비스에 있어야 한다고?

비즈니스 로직, 무조건 서비스에 두어야 할까?도메인 주도 설계(DDD)를 공부하다 보면 흔히 맞닥뜨리는 질문이 있다."비즈니스 로직이면 원래 서비스 레이어에 두는 거 아닌가?" 이 질문은 언뜻 맞는 말처럼 들리지만, 사실 절반만 맞는 말이다. 이 글에서는 비즈니스 로직의 위치에 대해 하나씩 짚어보며, 헷갈릴 수 있는 지점들을 정리해본다.서비스에 로직을 두는 게 맞는 경우다음과 같은 경우에는 비즈니스 로직을 서비스 레이어에 두는 것이 자연스럽다.여러 도메인 객체 간의 상호작용이 필요한 경우외부 시스템과의 연동이 포함되는 경우 (예: 메일 전송, 결제 API 호출 등)도메인 객체 내부에 두기엔 과도하거나 부적절한 경우예를 들어, "예약을 저장하고, 알림도 보내고, 결제도 트리거하는 흐름"이라면 이는 하나의 ..

DDD에서는 private을 지양한다?

DDD에서는 private을 지양한다?객체지향에서는 정보를 감추라고 하는데, 도메인 주도 설계에서는 왜 자꾸 public을 강조할까? 들어가며객체지향에서는 이렇게 배운다."메서드와 필드는 최대한 감춰라.""캡슐화를 통해 객체의 내부 구현을 보호해야 한다."그런데 도메인 주도 설계(DDD)를 공부하다 보면 이렇게 말한다.“비즈니스 규칙은 숨기지 말고, 드러내라.” 그럼 결국, private 쓰지 말라는 건가?헷갈릴 수밖에 없다.도메인 개념은 감추지 말고 드러내야 한다스케쥴을 체크하는 것은 꽤 중요한 도메인 개념이다.👉 그래서 다음과 같은 메서드를 외부에 열어주는 게 좋다.public boolean isSchedulable(LocalDateTime start, LocalDateTime end) { r..

도메인 로직과 비즈니스 로직 메모

도메인 로직(Domain Logic)도메인의 규칙과 행위 자체를 다루는 로직비즈니스의 본질적인 규칙들 (예: "환자가 같은 시간에 두 번 예약할 수 없다", "의사는 하루에 최대 20명만 진료 가능하다")Entity나 Value Object 안에 담기는 게 일반적변화 가능성은 낮고, 오히려 잘 구조화하면 유지보수성이 높아짐 비즈니스/애플리케이션 로직(Application Logic)요청 흐름을 제어하거나 유즈케이스 단위로 처리하는 로직예: "예약 요청을 받아서, 예약 가능한지 확인하고, 저장하고, 결과를 반환한다"보통 Service 계층에서 구현도메인 로직을 조합하고 orchestration 함도메인 모델은 이 시스템이 어떤 규칙을 가지는지 에 집중하고,애플리케이션 계층은 그 규칙을 언제, 어떻게 실행할..

DTO와 관련한 짧은 메모

record란 무엇인가? record는 자바 14부터 도입된 클래스의 일종이다. 따라서 내부적으로도 final class로 컴파일된다.즉, record는 불변 객체를 간편하게 만들기 위한 클래스의 축약 문법인 것이다!record 선언을 통해 자동 생성되는 것들은 다음과 같다.- 모든 필드 private final 선언- 생성자- Getter (필드명과 동일한 이름의 메서드)- equals() / hashCode()- toString()요즘엔 DTO를 record로 선언한다. 사실 DTO는 필드를 외부에 노출하고, 읽기만 하는 경우가 많다.그래서 불변성 + 간결함을 모두 가진 record랑 찰떡궁합이라고 볼 수 있다!DTO 클래스 이름 짓기는 어떻게? 이름 짓기라는 게 사실 스타일 차이라서 어떤 게 맞다고..

[🦁3] 객체 지향 설계: OOP

시청할 것우아한객체지향이번 주 키워드 정리상속(Inheritance) vs 조합(Composition)1. 상속(Inheritance)부모 클래스의 속성과 메서드를 자식 클래스가 물려받는 방식코드 재사용성이 높지만, 부모 클래스에 종속되어 강한 결합(High Coupling) 발생부모 클래스가 변경되면 자식 클래스에도 영향을 미쳐 유지보수가 어려워질 수 있음2. 조합(Composition)기존 클래스를 포함(Has-A 관계)하여 기능을 재사용하는 방식강한 결합을 피할 수 있어 유지보수가 용이하고 유연성이 높음상속보다 유연하며, 런타임 시 객체를 변경할 수도 있음🚀 언제 사용해야 할까?상속: 명확한 "is-a" 관계(예: Car is a Vehicle)조합: 유연한 "has-a" 관계(예: Car has..

드래그 방지 해제하기

어, 승준이형이야. 가끔 공부하다 보면 다른 사람 블로그에서 코드 참고할 때 있지?쓰라고 해놓고, 정작 드래그를 막아놔서 복사할 수가 없는 이상한 블로그들이 있어. 크롬 기준이고, 3초면 해결하니까 이번 기회에 알아두자.1. 개발자 도구 열기 (F12, Ctrl + Shift + I)단축키가 같은진 모르겠어.우측 상단에 점 세 개 있는 거 누르고 `도구 더보기` → `개발자 도구` 순으로 찾아서 열어도 돼. 2. Settings 접근하기 (F1)우측 상단에 톱니바퀴 눌러도 돼. 3. JavaScript 해제하기쭉 내려서 Debugger 블록 찾고, `Disable JavaScript` 체크하면 끝이야.원래는 코드를 찾아서 수정해줘도 되는데, 우린 귀찮으니까 그냥 자바스크립트를 해제하고 쓰자.

무분별한 Getter & Setter 사용은 OOP 원칙을 위배한다.

들어가기에 앞서, 우리는 Getter와 Setter에 대해 학습했다. OOP 원칙 중 캡슐화에 대해 인지하였고, 따라서 Setter 사용을 지양해야 한다는 것 정도는 이미 알고 있는 사실이다. 그렇다면 왜 Getter 사용도 지양해야 하는 걸까?또는, Setter를 지양해야 하는 명확한 이유는 뭘까?Getter와 Setter의 탄생 객체 지향은 정보 은닉에서 시작한다.객체 지향 언어의 장점은 물론 다양하겠지만, 가장 큰 장점 중 하나가 유연성이다. 이러한 설계 방식은 변화하는 요구사항에 쉽게 대응할 수 있도록 한다. 유연성을 가능하게 하는 요소는 무엇일까?바로, 1. 캡슐화 2. 상속 3. 다형성이다. 그중 캡슐화, 이하 정보 은닉은 내부 구현을 숨기고 필요한 부분만 외부에 공개하도록 한다. 외부 코드가..

[CS] 컴퓨터의 연산 방식 (feat. 1의 보수 & 2의 보수)

들어가기에 앞서,컴파일이란 무엇인가?  C, C++, Java, Python 같이 우리가 일반적으로 사용하는 프로그래밍 언어를 고급 언어라고 하며, 기계어와 어셈블리어를 저급 언어라고 한다. 가장 쉬운 구분법은 해당 언어가 인간친화적인지 기계친화적인지를 따지는 것이다.  인간친화적인 고급 언어는 우리가 읽고 쓰기 편하지만 이를 그대로 전달한다면 컴퓨터는 이해할 수 없다. 이유를 간단히 설명하자면, 컴퓨터는 전기 신호를 바탕으로 이해하는데 이를 `있다(1)`와 `없다(0)` 정도로만 구분하기 때문이다.  CPU가 직접 해석하고 실행할 수 있도록, 사람이 작성한 고급 언어인 `코드`를 `기계어`로 번역하는 것을 `컴파일`이라고 한다.소스 코드를 실행 가능한 파일로 만드는 전체 과정을 `빌드`라고 하며, 컴파..

개인 학습/CS 2025.03.26

[Spring] OOP: SOLID 원칙

Object-Oriented Programming 👉 객체지향 프로그래밍을 위한 다섯 가지 중요한 설계 원칙을 SOLID 원칙이라고 한다. *더보기는 관련 예시임 1. Single Responsibility Principle (단일 책임 원칙)하나의 클래스는 단 하나의 책임만 가져야 한다.즉, 여러 기능을 한 클래스에서 처리하지 않는다.더보기✅ 정보 저장 기능과 정보 출력 기능을 별도의 클래스로 분리2. Open/Closed Principle (개방-폐쇄 원칙)확장에는 열려 있고, 수정에는 닫혀 있어야 한다.즉, 기존 코드를 변경하지 않고 새로운 기능을 추가할 수 있도록 설계한다.더보기✅ 조건문 대신, 인터페이스나 추상 클래스를 사용하여 새로운 기능을 확장3. Liskov Substitution Pri..

고독한 개발 일기 #1

스프링이 뭔지도 모르는 이의 엉망진창 개발 일지입니다.읽지 않는 것을 추천드리오나, 고통에 몸부림치는 뉴비의 일기장이 궁금하다면 말리지 않습니다.2025-03-231:57 프로그램을 짤 때, 일단 컨트롤러부터 만든다고 한다.그래서 controller 패키지에 있던 ReservationController를 열었다. 가장 먼저, 필요한 어노테이션을 작성하라는 문구가 보였다.일단 컨트롤러니까 컨트롤러라고 명시했다.@Controller메서드에서 HTML 파일을 반환할 때 사용한다더라.지금 내가 갖고 있는 `index.html`이나 `revervation_form.html` 말하는 것 같다. 만약에 JSON을 반환해야 한다면 @RestController를 써야 한다더라.물론 이번 프로젝트는 웹 페이지를 렌더링하는..

[Java] 제네릭과 명명 관례

제네릭  제네릭은 용어에서 알 수 있듯이 범용적으로 사용하는 데 목적이 있다. 이는 메서드에 매개변수를 추가하는 것과 비슷한 맥락이지만 결정적인 차이가 있다.  메서드는 매개변수에 인자를 전달해서 사용할 값을 전달한다. 반면, 제네릭 클래스는 타입 매개변수에 타입 인자를 전달해서 사용할 타입을 결정한다.더보기를 생략한 Raw Type도 가능하지만 사용하지 않는다. Raw Type이 존재하는 이유는 과거 코드와의 하위 호환이 필요했기 때문에 지원할 뿐이다. 제네릭 명명 관례E - ElementK - KeyN - NumberT - TypeV - ValueS, U, V, etc.더보기타입 인자로 기본형(int)을 사용할 수 없으며, 대신 래퍼 클래스(Integer)를 사용한다.

[🦁2] Web App & Spring MVC #2

이번 포스트에서는 `스프링 MVC 동작 원리와 구현`을 다룹니다.학습 순서웹 애플리케이션 기본 원리스프링 MVC 동작 원리와 구현 📍 객체 지향 설계 원칙 (다음 주 예정)📚 세부 학습 순서Spring MVC 동작 원리DispatcherServlet의 역할 & 동작 방식Controller, View Resolver와의 관계Spring MVC 요청 처리 흐름 (Controller → Service → Repository)Spring을 활용한 REST API 구현REST의 특징 (HTTP 메서드, REST 제약 조건)@RestController와 REST API 구현Spring MVC 동작 원리DispatcherServlet의 역할 & 동작 방식  Spring MVC의 핵심 컴포넌트라고 할 수 있는 Di..

[🦁2] Web App & Spring MVC #1

이번 포스트에서는 `웹 애플리케이션 기본 원리`를 다룹니다.학습 순서웹 애플리케이션 기본 원리 📍 스프링 MVC 동작 원리와 구현객체 지향 설계 원칙 (다음 주 예정)*본 포스트에서 `더보기`는 추가 설명임📚 세부 학습 순서웹 애플리케이션의 기본 원리웹 애플리케이션프로토콜 (HTTP, HTTPS)Web Server와 WAS3계층 아키텍처스케일링 (아키텍처의 확장)웹 애플리케이션의 기본 원리웹 애플리케이션 🔹 Web App이란 `클라이언트`와 `서버` 간의 상호작용을 통해 동작하는 애플리케이션이다.클라이언트: 주로 사용자가 요청하는 `웹 브라우저`서버: 요청을 처리하는 `웹 서버`와 `WAS`🔹 웹 애플리케이션은 주로 `HTTP 프로토콜`을 이용하여 데이터를 주고받는다.클라이언트(웹 브라우저)가 U..

[🦁1] Git & GitHub

깃은 형상관리 시스템이다.학습 순서  기본적인 Git 사용법 → 변경 사항 관리 → 협업 & 고급 기능이번 주 키워드Working Directorygit reset & git revertgit stashConflictgit rebasecherry-pick1. Working Directory  우선, 깃의 추적 여부에 따라 `Untracked`와 `Tracked`로 나뉨. 여기서 깃의 추적이라고 함은 깃이 관리하는 파일인가를 뜻하는데, 깃의 관리 기준은 "git add를 한 번이라도 하였는가?"로 이해하면 쉬움.git add를 한 번도 하지 않은 새 파일 → Untrackedgit add를 한 번이라도 한 파일 → Tracked 파일이 한 번이라도 git add 된 경우 Tracked 상태가 유지되며, 해..

[Java] 알고리즘 설계 기법: 최적화 문제를 위한 DP

다이나믹 프로그래밍은 시간 단축을 위한 알고리즘이다. 탑다운 방식과 바텀업 방식이 존재하며, 결국 핵심은 계산한 값을 저장하고 재활용한다는 것이다.동적 계획법(DP)를 구현해 보자. 탑다운: 메모이제이션  이름에서 알 수 있듯 큰 문제부터 작은 문제로 해결하는 방식이다. ✅ 재귀구조가 직관적이고 구현이 간단하다. ✅ 재귀호출이 깊어질수록 스택 오버플로우 가능성이 있다.public class Fibonacci { static int[] dp; public static int fibonacci(int n) { if (n 바텀업: 터뷸레이션  이름에서 알 수 있듯 작은 문제부터 큰 문제로 해결하는 방식이다. ✅ 스택 오버플로우 위험이 없으며 모든 값에 쉽게 접근할 수 있다.✅ 반복문을 ..

[Java] 그래프 탐색 알고리즘: DFS, BFS

인사말  모두들 안녕하신가요.  저는 어느덧 알고리즘을 건든 지 140일 지났답니다. 기쁜 소식이 있어 전해드리자면, 최근에 BFS 문제들을 풀며 골드 구간에 진입했어요. 목표는 골랜디 마스터고요. 이번에 문제를 풀며 스스로 아쉬웠던 부분들이 있어서 지금의 생각과 감정을 기록하려고 글을 적습니다.BFS인데 그래프가 2개?package bfs;import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;import java.util.LinkedList;import java.util.Queue;public class Problem10026 { static final int[] dx = {0, 0, -1,..

[DA] 비전공자 ADsP 2일 전사 후기

ADsP 제44회 응시하였습니다. 번아웃이 와서 미루고 미루다가 시험 이틀 전부터 준비했습니다. 가채점 돌려보니 56-62점 사이로 나올 것 같네요. 기억나지 않는 게 딱 3문항 있거든요. 이 중에서 2개 이상 맞혔다면 턱걸이 합격 가능할 것 같습니다. (3월 14일 수정) 60점 합격했습니다.준비 과정 1일 차 유튜브 아답터가 유명하길래 일단 아래 영상부터 시청하였습니다. 시간이 촉박한지라 냅다 기출 박치기로 전략을 짰습니다. 들으면서 한 번에 이해하려고 하지 않았고 대강 들은 뒤 바로 기출로 넘어갔습니다. ADsP - 아답터 기출문제집은 작년에 데이터 분석 프로젝트를 마무리하며 선물 받은 게 있어서 「ADsP 모든 것」이라는 교재 사용했습니다. 1과목, 2과목 연습문제 위주로 싹 풀었어요. 대강 60..

자격증 2025.02.26

[Java] BOJ 18870: 좌표 압축과 랭킹 알고리즘

문제수직선 위에 N개의 좌표 X1, X2, ..., XN이 있다. 이 좌표에 좌표 압축을 적용하려고 한다. Xi를 좌표 압축한 결과 X'i의 값은 Xi > Xj를 만족하는 서로 다른 좌표 Xj의 개수와 같아야 한다. X1, X2, ..., XN에 좌표 압축을 적용한 결과 X'1, X'2, ..., X'N를 출력해보자.이해하기좌표 압축을 적용한 값 X'i가  Xi > Xj를 만족하는 서로 다른 좌표 Xj의 개수와 같다. 중복되는 원소가 같은 순위를 가진다는 점이 마치 SQL Server에서의 DENSE_RANK 느낌인데, 이 문제에서 추가로 고려할 점은 값이 작을수록 순위가 높다는 것과 가장 높은 순위는 0순위라는 점이다. 중복되는 원소를 같은 순위로 둔다는 점을 고려할 때, 일단 Set이나 Map을 활용..