You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
7주 간의 대장정이 끝이 났네요. 제가 예전에 '코드를 잘 짜야한다는게 뭐지? 그냥 기능이 문제 없이 돌아가면 되는거 아닌가?' 라고 생각한 적도 있었고 '아, 나도 누가 봤을 때 코드 잘 짰다는 말을 듣고 싶다.' 또는 '와, 이 사람 코드 진짜 잘 짰네?'라고 말할 수 있는게 멋있어 보여서 저도 그렇게 되고 싶었습니다. 그래서 잘 짠 코드에 기준이 뭘까 라는 생각을 꾸준히는 해왔는데 이번 토끼책을 읽으면서 정말 코딩을 한다는 것이 단순히 기능만 잘 돌아가도록 하는 것이 아니라 앞으로의 변화하는 요구사항들도 수용하도록 설계 단계부터 잘 쌓아올려야 되는구나라고 생각했습니다. 그리고 인터페이스와 구현을 분리해서 안정적이면서도 변화에 능한 코드가 좋은 코드구나라는 것을 어렴풋이 스터디를 진행하면서 깨닫게 된 것 같습니다. 이 책이 처음에는 같이 이야기만 반복하고 정말 좋은 책이 맞나 의문이 들었지만 지금 되돌아 보면 저에게 객체지향을 바라보는 시야를 좀 더 넓혀준 책인 것 같습니다. (역할, 책임, 협력, 메시지 잊지 않을게)
세 줄 요약
단순히 동작하는 코드보다 변화에 유연하고 잘 설계된 코드가 좋은 코드임을 깨달았다.
인터페이스와 구현의 분리가 안정적인 객체지향 설계의 핵심이라는 걸 스터디를 통해 체감했다.
토끼책은 처음엔 낯설었지만, 객체지향의 본질과 시야를 넓혀준 소중한 경험이 되었다.
📖 핵심 내용 요약
(새롭게 알게 된 개념 정리)
(관련된 코드 예제 또는 설명 추가)
객체지향 설계 속 상호 연관된 관점
개념 관점(Conceptual Perspective) : 도메인 안에 존재하는 개념과 개념들 사이의 관계를 표현, 실제 도메인의 규칙과 제약을 최대한 유사하게 반영하는 것이 핵심
명세 관점(Specification Perspective) : 객체가 협력을 위해 '무엇'을 할 수 있는가에 초점을 맞춤
구현 관점(Implementation Perspective) : 객체들이 책임을 수행하는 데 필요한 동작하는 코드를 작성하는 것에 초점 맞춤
클래스로 보는 세 가지 관점
개념 관점 : 클래스가 은유하는 개념, 표현적 차이가 좁을수록 유지보수성이 높다.
명세 관점 : 클래스의 공용 인터페이스, 구현과 관련된 세부 사항이 드러나지 않게 해야함.
구현 관점 : 클래스의 속성과 메서드, 메서드와 속성이 철저하게 클래스 내부로 캡슐화돼야 한다.
예시) 재능 매칭 시스템
목표
사람들이 자신의 재능을 등록하고, 다른 사람의 재능과 교환할 수 있는 공간 제공
개념 관점
시스템이 어떤 “의미”를 가지는지, 사용자 입장에서 무엇을 하는 시스템인지를 설명하는 단계
주요 개념 요소 (개념 클래스)
개념 클래스
역할
설명
User
Giver or Receiver
두 역할을 모두 할 수 있음 (상황에 따라 역할 전환)
Skill
Giver가 보유
Giver가 제공하는 재능
Request
Receiver가 생성
Receiver가 Giver의 재능을 받고 싶다고 요청
Match
교환 결과
Giver와 Receiver가 연결된 상태
Schedule
Match에 종속
만남/수업 일정 정보
Review
Match 이후
Receiver가 Giver에게 남기는 후기
개념 관점에서 체크!
체크 항목
설명
예시
1. 개념 클래스가 도메인을 잘 표현하는가?
사용자 입장에서 익숙한 용어로 시스템을 설명하고 있는가?
User, Skill, Match 등은 일상 언어 기반으로 설계되어 이해하기 쉬움 ✅
2. 역할이 명확하고 혼동되지 않는가?
각 개념이 하는 일이 명확하고 겹치지 않는가?
User는 Giver/Receiver 둘 다 가능하지만, 문맥에 따라 명확히 역할 구분되어 있음 ✅
3. 실제 시나리오를 설명할 수 있는가?
이 개념들로 실제 사용 흐름을 자연스럽게 말할 수 있는가?
"User가 Skill을 등록하고, 다른 User가 Request를 보내면 Match가 생성됨" → 자연스럽게 설명 가능 ✅
4. 불필요하거나 중복된 개념이 없는가?
비슷한 역할을 하는 클래스가 중복되거나 불필요한 것이 없는가?
Match와 Request가 구분되어 있고, 의미가 명확히 다름 ✅
5. 개념 간 관계가 현실적인가?
관계가 실제 사람 간 상호작용처럼 자연스러운가?
Match가 Schedule과 Review를 포함 → 실제 만남과 후기 흐름을 잘 반영 ✅
명세 관점
각 객체가 어떤 메시지를 주고받고, 어떤 역할을 수행하는 지를 정의한 협력 중심 관점
(각 메시지는 공용 인터페이스의 역할로 이해하면 됩니다.)
User
역할: 재능을 등록하거나 요청하는 행위의 주체 (Giver / Receiver 역할 모두 가능)
수신 메시지 (역할 기반 인터페이스)
registerSkill(Skill skill) : 재능을 등록한다
requestSkill(Skill skill) : 다른 사람의 재능에 요청을 보낸다
respondToRequest(Request request, boolean accepted) : 받은 요청에 응답한다
Schedule.reschedule()과 Schedule.conflictsWith()는 같은 클래스에 ✅
5. 객체의 상태 변경이 예측 가능하고 안전한가?
상태 변경이 적절한 메서드를 통해서만 일어나며, 무결성이 깨지지 않도록 검증 로직 포함
match.complete() → 완료 상태로만 전이, 이미 완료 상태일 경우 예외 처리 ✅
6. 테스트하기 쉬운 구조인가?
의존성 분리, 명확한 책임 분리 등으로 유닛 테스트 작성이 쉬운가?
User가 SkillRepository에 직접 접근 ❌ → 생성자 주입으로 분리 ✅
결론
세 가지 관점(개념, 명세, 구현)을 모두 고려해서 객체지향 코드를 작성해야 하며, 각 관점을 모두 포함하면서도 각 관점에 대응되는 요소를 명확히 드러내는 것이 중요하다는 것을 알았습니다. 개념 관점은 도메인에 맞는 구조를 설계하고, 명세 관점은 안정적인 인터페이스를 정의하며, 구현 관점은 내부 세부사항을 캡슐화하여 외부에 영향을 미치지 않도록 합니다. 이를 통해 유지보수성을 높이고, 코드 변경에 유연하게 대응할 수 있는 객체지향 설계를 할 수 있다는 것을 이번 장을 통해서 알 수 있었습니다.
❓ 어려웠거나 이해가 부족했던 부분
🔍 명확히 이해되지 않은 개념
🔍 다른 사람과 토론해보고 싶은 부분
💭 궁금한 점
(이해되지 않는 부분 정리)
(다른 접근 방식이 있을지 고민)
💡 토론해 보고 싶은 질문
"이 개념이 실제 코드에서는 어떻게 쓰일까요?"
"이걸 다르게 접근할 수도 있지 않을까요?"
"기술 면접 대비: 제가 면접관이라면 이 부분에서 이런 질문을 할 것 같아요."
🌟 인상 깊었던 책의 내용
📝 특히 기억에 남는 문장이나 사례
📝 왜 인상 깊었는지, 어떻게 적용할 수 있을지 고민
📌 기억에 남는 문장
"설계를 간단히 끝내고 최대한 빨리 구현에 돌입하라."
토끼책을 완독하면서 어느정도 이론적인 개념들은 배웠으니까 이를 바탕으로 이제는 직접 설계해보고 코드를 작성하는 단계에 돌입을 해야겠다고 생각해서 기억에 남았습니다.
🔎 적용 방법 고민
이론적으로는 무슨 말인지 알겠는데 실제로 개발할 때 적용하기 뭔가 쉽지 않을 것 같다는 생각이 들었습니다..
그래서 정말 작은 규모의 프로젝트라도 먼저 직접 해보면서 데이터를 쌓아가야겠다고 생각했습니다.
📚 관련 아티클 & 추가 자료
📌 다른 사람이 이해하는 데 도움이 될 만한 자료 첨부
📌 논문, 블로그, 영상, 실무 사례 등 공유
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
🆕 새롭게 알게 된 점
7주 간의 대장정이 끝이 났네요. 제가 예전에 '코드를 잘 짜야한다는게 뭐지? 그냥 기능이 문제 없이 돌아가면 되는거 아닌가?' 라고 생각한 적도 있었고 '아, 나도 누가 봤을 때 코드 잘 짰다는 말을 듣고 싶다.' 또는 '와, 이 사람 코드 진짜 잘 짰네?'라고 말할 수 있는게 멋있어 보여서 저도 그렇게 되고 싶었습니다. 그래서 잘 짠 코드에 기준이 뭘까 라는 생각을 꾸준히는 해왔는데 이번 토끼책을 읽으면서 정말 코딩을 한다는 것이 단순히 기능만 잘 돌아가도록 하는 것이 아니라 앞으로의 변화하는 요구사항들도 수용하도록 설계 단계부터 잘 쌓아올려야 되는구나라고 생각했습니다. 그리고 인터페이스와 구현을 분리해서 안정적이면서도 변화에 능한 코드가 좋은 코드구나라는 것을 어렴풋이 스터디를 진행하면서 깨닫게 된 것 같습니다. 이 책이 처음에는 같이 이야기만 반복하고 정말 좋은 책이 맞나 의문이 들었지만 지금 되돌아 보면 저에게 객체지향을 바라보는 시야를 좀 더 넓혀준 책인 것 같습니다. (역할, 책임, 협력, 메시지 잊지 않을게)
📖 핵심 내용 요약
객체지향 설계 속 상호 연관된 관점
클래스로 보는 세 가지 관점
예시) 재능 매칭 시스템
목표
사람들이 자신의 재능을 등록하고, 다른 사람의 재능과 교환할 수 있는 공간 제공
개념 관점
시스템이 어떤 “의미”를 가지는지, 사용자 입장에서 무엇을 하는 시스템인지를 설명하는 단계
주요 개념 요소 (개념 클래스)
개념 관점에서 체크!
User,Skill,Match등은 일상 언어 기반으로 설계되어 이해하기 쉬움 ✅User는 Giver/Receiver 둘 다 가능하지만, 문맥에 따라 명확히 역할 구분되어 있음 ✅Match와Request가 구분되어 있고, 의미가 명확히 다름 ✅Match가Schedule과Review를 포함 → 실제 만남과 후기 흐름을 잘 반영 ✅명세 관점
각 객체가 어떤 메시지를 주고받고, 어떤 역할을 수행하는 지를 정의한 협력 중심 관점
(각 메시지는 공용 인터페이스의 역할로 이해하면 됩니다.)
User
역할: 재능을 등록하거나 요청하는 행위의 주체 (Giver / Receiver 역할 모두 가능)
수신 메시지 (역할 기반 인터페이스)
registerSkill(Skill skill): 재능을 등록한다requestSkill(Skill skill): 다른 사람의 재능에 요청을 보낸다respondToRequest(Request request, boolean accepted): 받은 요청에 응답한다scheduleMatch(Match match, Schedule schedule): 매칭된 교환의 일정을 조율한다writeReview(Match match, String content, int rating): 교환이 끝난 후 후기를 작성한다Skill
역할: 기부자가 보유한 재능의 정보 단위
수신 메시지
getOwner(): 이 재능을 보유한 사용자 반환updateDescription(String newDesc): 재능 설명 수정isMatchable(): 현재 교환 가능한 상태인지 확인Request
역할: 수혜자가 기부자의 재능에 대해 보낸 요청
수신 메시지
accept(): 요청을 수락한다reject(): 요청을 거절한다getStatus(): 현재 요청의 상태(PENDING, ACCEPTED, REJECTED)를 반환한다getTargetSkill(): 요청 대상 재능을 반환getRequester(): 요청을 보낸 사용자 반환Match
역할: 교환이 성사된 상태 (Request → Match로 전환됨)
수신 메시지
setSchedule(Schedule schedule): 교환 일정 설정complete(): 교환을 완료 상태로 변경isCompleted(): 교환 완료 여부 반환attachReview(Review review): 후기 연결Schedule
역할: 교환이 이루어질 시간 정보
수신 메시지
reschedule(LocalDateTime newTime): 시간을 변경한다conflictsWith(Schedule other): 일정 간 충돌 여부 확인getTime(): 일정 시간 반환Review
역할: 교환 이후 작성되는 평가
수신 메시지
getRating(): 평점 반환getContent(): 후기 내용 반환edit(String newContent, int newRating): 후기 수정객체 간 관계 요약
명세 관점에서 체크!
requestSkill()→ 스킬 요청 기능 요구사항을 명확히 반영sendEmail,calculateDiscount)애매한 이름은 설계 오류 가능성 있음
createNewUser()❌ →registerUser()✅User.writeReview()✅,Review.write()❌ (User가 후기를 쓰는 게 자연스럽기 때문)Schedule.reschedule()✅ → 다른 객체와 관계없이 자기 책임만 수행Request.accept()내에서 Match 생성 후 이벤트 발행 → 추후 알림 기능 추가 시에도 변경 최소화 ✅구현 관점
역할을 부여 받은 객체들이 책임을 수행하는 데 필요한 동작하는 코드를 작성하는 것에 초점 맞춤
예시코드
코드 핵심 요약
User 클래스:
registerSkill,requestSkill,respondToRequest,writeReviewSkill 클래스:
isMatchable,updateDescriptionRequest 클래스:
accept,reject,getStatusMatch 클래스:
setSchedule,complete,attachReviewSchedule 클래스:
reschedule,conflictsWithReview 클래스:
edit구현 관점에서 체크!
private, 접근은 메서드로. 내부 상태를 직접 노출하지 않도록 설계user.name = "John"❌ →user.getName("John")✅User.writeReview()✅,Match.writeReview()❌ (후기는 User의 책임)Skill을 수정해도Review와 무관해야 함Schedule.reschedule()과Schedule.conflictsWith()는 같은 클래스에 ✅match.complete()→ 완료 상태로만 전이, 이미 완료 상태일 경우 예외 처리 ✅User가SkillRepository에 직접 접근 ❌ → 생성자 주입으로 분리 ✅결론
세 가지 관점(개념, 명세, 구현)을 모두 고려해서 객체지향 코드를 작성해야 하며, 각 관점을 모두 포함하면서도 각 관점에 대응되는 요소를 명확히 드러내는 것이 중요하다는 것을 알았습니다. 개념 관점은 도메인에 맞는 구조를 설계하고, 명세 관점은 안정적인 인터페이스를 정의하며, 구현 관점은 내부 세부사항을 캡슐화하여 외부에 영향을 미치지 않도록 합니다. 이를 통해 유지보수성을 높이고, 코드 변경에 유연하게 대응할 수 있는 객체지향 설계를 할 수 있다는 것을 이번 장을 통해서 알 수 있었습니다.
❓ 어려웠거나 이해가 부족했던 부분
💭 궁금한 점
💡 토론해 보고 싶은 질문
🌟 인상 깊었던 책의 내용
📌 기억에 남는 문장
토끼책을 완독하면서 어느정도 이론적인 개념들은 배웠으니까 이를 바탕으로 이제는 직접 설계해보고 코드를 작성하는 단계에 돌입을 해야겠다고 생각해서 기억에 남았습니다.
🔎 적용 방법 고민
이론적으로는 무슨 말인지 알겠는데 실제로 개발할 때 적용하기 뭔가 쉽지 않을 것 같다는 생각이 들었습니다..
그래서 정말 작은 규모의 프로젝트라도 먼저 직접 해보면서 데이터를 쌓아가야겠다고 생각했습니다.
📚 관련 아티클 & 추가 자료
🔗 추천 자료
Beta Was this translation helpful? Give feedback.
All reactions