본문 바로가기

전체 글

(72)
[행동 관련 디자인 패턴] 전략 패턴(Strategy) - ❾ GoF 행동 패턴 학습 기록 ❾들어가며바뀌는 부분만 인터페이스로 빼서, 밖에서 골라 끼우는 방식.상태 패턴(❽)이 "상태를 객체로"였다면, 전략은 "정책(알고리즘)을 객체로 ! 구조는 둘이 같고 차이는 상태냐 정책이냐.아래 코드와 출력은 JDK 21, Kotlin 2.1.0, Spring 6.1 환경에서 실제로 컴파일하고 실행한 결과다.1. 문제 — 정책이 늘어날 때마다 if문이 늘어난다회원 등급별 할인을 계산하는 코드다.int discount(String grade, int price) { if (grade.equals("일반")) return price; else if (grade.equals("실버")) return price - price * 5 / 100; else if..
[행동 관련 디자인 패턴] 상태 패턴(State) - ❽ GoF 행동 패턴 학습 기록 ❽들어가며상태 패턴 요약if로 상태를 검사하는 대신, 상태를 객체로 만들어 그 객체에게 물어보는 방식. 아래 코드와 출력은 JDK 21, Kotlin 2.1.0 환경에서 실제로 컴파일하고 실행한 결과다.1. 신호등으로 보기신호등은 빨강 → 초록 → 노랑 → 빨강 순서로 돌아가고, 색마다 행동에 대한 패턴이 다르다.IF — 상태를 '값'으로 두기class LightIf { String color = "빨강"; void next() { if (color.equals("빨강")) color = "초록"; else if (color.equals("초록")) color = "노랑"; else if (color.equals("노랑")) c..
[행동 관련 디자인 패턴] 옵저버 패턴(Observer) - ❼ GoF 행동 패턴 학습 기록 ❼들어가며이번 공부에서 나온 의문.이벤트 리스너도 옵저버인가? (맞다)그럼 브로커는 뭐고, 리스너 인터페이스를 만들면 그게 브로커인가? (아니다)이벤트 리스너가 커밋을 확인할 수 있는 건 어떻게 되는 건가?코드는 전부 실제로 컴파일하고 실행해서 출력을 확인했다. (JDK 21 / Kotlin 2.1.0 / Spring 6.1)1. 한 줄 정의와 문제상태가 바뀌면 관심 있는 객체들에게 자동으로 알린다."자동으로"가 핵심이다. 구독자가 계속 물어보는(폴링) 대신 발행자가 밀어주는 구조로 뒤집는 것이다. 패턴 없이 짜면 아래와 같다.// ① 폴링 — 구독자가 계속 물어본다while (true) { List messages = server.getMessages("공지"); ..
[행동 관련 디자인 패턴] 메멘토 패턴(Memento) - ❻ GoF 행동 패턴 학습 기록 ❻ — "복원했는데 일부만 복원된다?"들어가며메멘토는 구조가 단순하다. 상태를 스냅샷 형식으로 저장했다가 되돌린다. 그런데 정리하면서 의문이 생겼다.스냅샷 뜨면 다 메멘토인가? (아님)커맨드 undo랑 뭐가 다른가? (접근 방식이 정반대)코드는 전부 실제로 컴파일하고 실행해서 출력을 확인했다. (JDK 21 / Kotlin 2.1.0)1. 한 줄 정의와 세개의 역할캡슐화를 유지하면서 객체 내부 상태를 외부에 저장하는 방법."캡슐화를 유지하면서"가 포인트다. 저장/복원만 하는 거면 getter를 사용해라.역할정체예제에서Originator상태의 주인. 저장/복원을 직접 함GameMemento저장된 스냅샷. 불변SaveCaretaker스냅샷을 보관만 함. 내용은 모름History2..
[행동 관련 디자인 패턴] 중재자 패턴(Mediator) - ❺ GoF 행동 패턴 학습 기록 ❺ — 퍼사드랑 헷갈렸고, 예제를 잘 봐야하는 패턴들어가며중재자 패턴을 호텔 프론트 데스크 예제로 공부했다. 손님이 수건을 요청하면 프론트가 청소부에게 넘기고, 저녁 예약을 하면 식당에 넘긴다. 창구 하나로 모았으니 중재자다 — 싶었는데 정리하다 이건 퍼사드 아닌가? 생각이 들었다.참조 방향. 퍼사드는 단방향, 중재자는 양방향.그 뒤에 순환 참조 얘기가 줄줄이 따라 나왔다. "요즘 IntelliJ가 다 잡아주는데?", "세터 주입? 의문이 드는데?" 궁금증이 생겼고, 이 글은 그 정리다. 코드는 전부 실제로 컴파일하고 실행해서 출력을 확인했다. (JDK 21 / Kotlin 2.1.0)1. 한 줄 정의와 문제여러 객체들이 소통하는 방법을 캡슐화하는 패턴.쉽게 말하면 관제탑이다..
[행동 관련 디자인 패턴] 이터레이터 패턴(Iterator) - ❹ GoF 행동 패턴 학습 기록 ❹ — 이미 매일 쓰고 있었던 패턴들어가며"이게 패턴인가?" for-each는 그냥 문법이고, Iterator는 그냥 JDK API인데?패턴인지 인지 못한 이유는 이터레이터는 너무 성공해서 언어에 흡수된 패턴이라 그렇다. 1994년 GoF 당시엔 순회를 어떻게 추상화할지가 실제 미해결 문제였고, 자바에 Iterator가 들어온 건 1998년(JDK 1.2), for-each 문법은 2004년(Java 5)에 만들어졌다. 그리고 내가 Iterator를 손으로 꺼내 쓴 이유가 딱 하나였는데, 그게 이 패턴의 본질에서 정확히 파생된 것이었다.코드는 전부 실제로 실행해서 출력을 확인했다. (JDK 21 / Kotlin 2.1.0)1. 한 줄 정의 — 책갈피컬렉션이 "무엇을 담을지"..
[행동 관련 디자인 패턴] 인터프리터 패턴(Interpreter) - ❸ GoF 행동 패턴 학습 기록 ❸ — 어려운 줄 알았는데, 알고 보니 간단했던 패턴들어가며인터프리터 패턴을 보기 시작했을 때 자료마다 파서(parser)가 같이 나왔다. 재귀 하강 파서, 토크나이저, 연산자 우선순위...그런데 정리해보니 패턴 자체는 간단했다. 어려웠던 건 패턴이 아니라 파서였고, 파싱은 인터프리터 패턴을 일부분만 쓴다.GoF는 "이미 만들어진 트리를 어떻게 해석하느냐"만 다룬다.트리로 객체화한다. 그 트리가 문법이고, 재귀로 해석한다.이 글은 위의 한 줄에 도달하는 과정과, 그래서 실무에서 언제 쓰고 언제 안 쓰는지를 정리한 기록이다. (JDK 21 / Kotlin 2.1.0)1. 이미 알고 있는 것부터 — 폴더 용량폴더 용량 계산을 생각해보자.프로젝트/├── 메모.txt (..
[행동 관련 디자인 패턴] 커맨드 패턴 심화 : Runnable로 읽는 java.util.concurrent - ❷ GoF 행동 패턴 학습 기록 ❷ 심화편 — 스레드풀을 커맨드 패턴으로 다시 읽기들어가며execute()에 파라미터가 없다 = 필요한 걸 다 들고 있다 = 그래서 저장&전달&재실행&되돌리기가 가능하다.그리고 "Runnable이 커맨드 패턴의 최소 형태"라고 한 줄 적고 넘어갔는데, 파보니까 그게 한 줄로 끝날 얘기가 아니었다.java.util.concurrent 패키지 전체가 커맨드 패턴 위에 지어져 있었다.Executor 인터페이스의 파라미터 이름이 실제로 command다submit()은 내가 넘긴 커맨드를 다른 커맨드로 감싼다그 사실 하나로 submit()이 예외를 삼키는 이유가 전부 설명된다@Async에서 traceId가 사라지는 문제도 같은 구조에서 나온다 JDK 21 / Kotlin 2.1.01...