Community코딩 & 개발github.com

yutna/oo-design

객체지향 코드베이스에서 새로운 모듈, 기능 또는 시스템을 시작하거나, 설계 규모를 결정하거나, 어떤 객체 규칙을 적용해야 할지 확실하지 않을 때 사용합니다.

oo-design란 무엇인가요?

이 스킬은 객체지향 코드베이스를 위한 설계 규칙 모음입니다. 프로젝트 고유의 규칙이 최우선이며, 이 스킬은 작업에 적합한 설계 규모를 결정하고 적절한 하위 스킬을 안내합니다. 작업의 범위(단일 메서드, 새 클래스, 완전히 새로운 시스템 등)에 따라 필요한 설계 활동을 제시하며, '설계 루프'라는 7단계 프로세스를 통해 도메인 언어 사용, 객체 책임 할당, 일관성 경계 설정, 의존성 역전, 네이밍 및 리뷰까지 체계적으로 진행합니다. 각 규칙은 '규칙', '기본값', '판단'이라는 엄격도 레이블로 구분되어 적용됩니다. 또한 수많은 설계 증상(예: '이 클래스가 너무 많은 일을 한다', 'setter가 객체 규칙을 위반한다')을 해결하는 스킬들을 연결하는 방대한 테이블을 제공하며, Java, Kotlin, TypeScript 등 언어별 특화 스킬도 지원합니다.

지원 대상✓Claude Code~Codex CLI~Cursor
npx skills add https://github.com/yutna/object-oriented-design-skills/tree/HEAD/plugins/core/skills/oo-design

Installed? Explore more 코딩 & 개발 skills: steipete/bluebubbles, steipete/eightctl, steipete/blucli · View all 6 →

즐겨 사용하는 AI에게 물어보기

이 에이전트 스킬이 미리 로드된 새 채팅을 엽니다.

문서

객체지향 설계

개요

이 팩은 객체지향 스타일로 작성된 코드베이스를 위한 설계 규칙이지, 보편적인 조언이 아닙니다. 프로젝트 자체의 작성 규칙이 이 팩보다 우선합니다. 변경 중인 모듈의 관용구를 따르세요. 이 스킬은 작업 규모를 결정하고 적합한 스킬을 명명합니다.

답변하기 전에 이 색인이 가리키는 스킬을 로드하세요. 해당 스킬의 규칙과 예제는 그곳에 있습니다.

작업에 필요한 설계 규모

작업사용건너뛰기
한 번 사용하고 버리는 답변아무것도 하지 않음모든 것
존재하는 클래스의 한 메서드메서드 이름과 계약재설계
기존 흐름 내부의 기능해당 흐름의 관용구새로운 경계
새 클래스 또는 모듈설계 루프모든 것
새로운 컨텍스트루프, 그다음 경계모든 것
완전히 새로운 시스템루프, 컨텍스트, 그다음 구조모든 것

설계 전

설계 전에 게이트를 명시하세요. 소프트웨어가 따라야 할 하나의 규칙과, 이 규칙이 허용하는 예제 하나, 거부하는 예제 하나를 제시하세요. 예를 들어 "슬롯은 최대 하나의 약속만 가질 수 있다."라는 규칙은 다른 슬롯에 두 번째 환자를 예약하는 것은 허용하지만, 같은 슬롯에 두 번째 환자를 예약하는 것은 거부합니다. 규칙을 적을 수 있으면 시작하세요. 적을 수 없으면, 부족한 것은 설계가 아니며 이 팩이 제공할 수 있는 것도 아닙니다.

설계 루프

  1. 도메인의 언어로 소프트웨어가 무엇을 해야 하는지 말하고(도메인 언어 사용), 각 동작에 필요한 것을 아는 객체를 찾으세요(책임 할당).
  2. 일관성 경계를 찾으세요. 하나의 트랜잭션에서 함께 참이어야 하는 것은 무엇인가요?(집합체 설계).
  3. 각 규칙이 어디에 위치할지 결정하세요. 엔티티, 값 객체 또는 도메인 서비스 중 어디인가요?(도메인 로직 배치).
  4. 각 객체가 응답하는 메시지를 설계하고(상태와 동작 캡슐화), 불가능한 상태를 구성할 수 없도록 만드세요(불가능한 상태 만들기).
  5. 도메인이 데이터베이스나 프레임워크를 알지 못하도록 의존성을 역전시키세요(의존성 역전, 시스템 계층화).
  6. 도메인의 언어로 이름을 짓고, 코드가 말할 수 없는 것만 주석으로 남기세요(클래스와 메서드 이름 짓기, 코드가 말할 수 없는 것에 주석 달기).
  7. 아래의 위험 신호와 결과를 대조하세요(객체 설계 검토).

규칙의 엄격도

이 팩의 모든 핵심 규칙은 다음 세 가지 레이블 중 하나를 가지며, 이 레이블이 규칙이 얼마나 엄격하게 적용되는지를 나타냅니다.

  • 규칙. 위반하면 결함입니다. 어떤 프레임워크도 이를 면제하지 않습니다.
  • 기본값. 명시된 조건이 성립하지 않는 한 이렇게 하세요. 조건은 독립적인 문장이며, 절대로 뒷부분에 붙는 절이 아닙니다.
  • 판단. 두 가지 답변이 모두 방어 가능합니다. 스킬은 어떤 것이 균형을 기울이는지 알려줍니다.

증상과 스킬

증상은 이를 치료하는 스킬을 가리키며, 이 표는 스킬이 추가됨에 따라 커집니다.

증상스킬
이 작업을 어떤 클래스가 수행해야 하나요?책임 할당
이 클래스가 너무 많은 일을 합니다책임 할당
변경 사항이 여러 클래스로 퍼져나갑니다결합도 진단
이 두 부분은 얼마나 단단히 결합되어 있나요?결합도 진단
이것은 객체인가요 아니면 단순한 데이터인가요?객체 또는 데이터 결정
우리의 도메인 모델이 빈약합니다객체 또는 데이터 결정
다른 코드가 이 객체를 대신해 결정합니다상태와 동작 캡슐화
Setter가 이 객체가 규칙을 위반하도록 만듭니다상태와 동작 캡슐화
이 객체가 반쯤 만들어진 상태로 존재할 수 있습니다유효한 객체 구성
이 생성자가 너무 많은 인수를 받습니다유효한 객체 구성
새로운 경우마다 작동 중인 코드를 수정해야 합니다변하는 것 캡슐화
이것이 얼마나 유연해야 하나요?변하는 것 캡슐화
이것은 값인가요 엔티티인가요?값과 엔티티 모델링
원시 문자열과 숫자가 도메인 규칙을 전달합니다값과 엔티티 모델링
이것은 저 클래스를 확장해야 하나요, 아니면 포함해야 하나요?상속보다 합성 선택
기본 클래스를 변경하면 하위 클래스가 깨집니다상속보다 합성 선택
하위 클래스가 부모의 약속을 위반합니다대체 가능성 존중
코드가 어떤 하위 타입인지 확인합니다대체 가능성 존중
동일한 타입에 대한 switch 문이 계속 나타납니다조건문을 다형성으로 대체
하위 클래스인가요 패턴 매칭인가요?조건문을 다형성으로 대체
코드가 객체 체인을 통해 도달합니다객체가 아는 것 제한
이 클래스는 호출만 전달합니다객체가 아는 것 제한
이 클래스나 메서드를 어떻게 불러야 하나요?클래스와 메서드 이름 짓기
Manager, Helper, Util 같은 이름클래스와 메서드 이름 짓기
호출자가 절대 사용하지 않는 인터페이스 메서드에 의존합니다인터페이스 설계
인터페이스인가요 추상 기본 클래스인가요?인터페이스 설계
도메인 코드가 데이터베이스나 프레임워크에 의존합니다의존성 역전
객체는 어디에서 생성되고 연결되나요?의존성 역전
호출자가 다른 클래스가 데이터를 저장하거나 형식화하는 방식을 압니다구현 숨기기
클래스가 내부 오류나 단계를 누설합니다구현 숨기기
플래그나 선택적 필드가 불가능한 조합을 허용합니다불가능한 상태 만들기
타입이 도메인이 절대 가지지 않는 값을 허용합니다불가능한 상태 만들기
코드의 단어가 직원들의 단어와 다릅니다도메인 언어 사용
하나의 단어가 두 팀에게 다른 의미를 갖습니다도메인 언어 사용
어떤 객체들이 함께 변경되어야 하나요?집합체 설계
저장 충돌이 발생하거나 한 번 로드할 때 너무 많은 데이터를 가져옵니다집합체 설계
어떤 상태 변경이 허용되나요?생명주기 모델링
취소되거나 종료된 객체가 다시 변경됩니다생명주기 모델링
도메인 객체를 어떻게 저장하고 찾아야 하나요?리포지토리 설계
리포지토리가 화면마다 find 메서드를 가지고 있습니다리포지토리 설계
유스케이스가 동일한 비즈니스 검사를 반복합니다도메인 로직 배치
도메인 서비스, 엔티티 메서드, 아니면 애플리케이션 서비스?도메인 로직 배치
변경 사항이 저장된 후 다른 부분이 반응해야 합니다도메인 이벤트 발행
롤백된 변경 사항에 대한 메시지가 나갔습니다도메인 이벤트 발행
한 팀의 모델이 끝나고 다른 팀의 모델이 시작되는 지점은 어디인가요?컨텍스트 경계 설정
어느 부분이 핵심이고, 어느 부분을 구매할 수 있나요?컨텍스트 경계 설정
계층은 어떤 방향으로 의존해야 하나요?시스템 계층화
화면이나 작업이 프레임워크 없이 테스트될 수 없습니다시스템 계층화
모듈이 순환적으로 서로 의존합니다모듈 구성
모듈형 모놀리스인가요, 아니면 별도의 서비스인가요?모듈 구성
API 변경이 이를 호출하는 앱을 중단시킵니다시스템 경계 넘기
이 API나 메시지의 버전을 어떻게 관리해야 하나요?시스템 경계 넘기
매핑 도구가 우리의 도메인 클래스를 왜곡합니다영속성 제어
리스트가 행당 하나의 쿼리를 실행합니다영속성 제어
화면은 모델과 다른 형태의 데이터가 필요합니다읽기와 쓰기 분리
읽기 모델, 프로젝션, 또는 이벤트 소싱?읽기와 쓰기 분리
이 화면에 MVC, MVP, MVVM 중 무엇인가요?프레젠테이션과 도메인 분리
화면이 도메인 객체를 직접 편집합니다프레젠테이션과 도메인 분리
어떤 디자인 패턴이 이 문제에 적합한가요?패턴 선택
문제보다 먼저 패턴이 추가되었습니다패턴 선택
이 패턴 클래스들은 함수일 수 있습니다언어가 제공하는 패턴
Visitor인가요, 아니면 매칭이 있는 닫힌 집합인가요?언어가 제공하는 패턴
메서드가 아무것도 찾지 못했을 때 null을 반환합니다실패 동작 설계
거부가 호출자가 무시하는 코드로 돌아옵니다실패 동작 설계
스레드가 객체를 공유하여 변경 사항을 잃거나 섞습니다공유 상태 관리
이 상태에 대한 잠금인가요, 아니면 단일 소유자인가요?공유 상태 관리
다른 시스템에 대한 호출이 중간에 멈추거나 실패합니다작업 신뢰성 확보
재시도가 작업을 두 번 수행했습니다작업 신뢰성 확보
기록으로 사건을 설명할 수 없습니다기록할 내용 설계
무엇을 로깅, 카운팅 또는 감사해야 하나요?기록할 내용 설계
리뷰에서 신 클래스나 용암 흐름을 발견했습니다안티패턴 인식
어떤 안티패턴을 먼저 수정해야 하나요?안티패턴 인식
동작이 변경되지 않았는데 테스트가 실패합니다객체지향 코드 테스트
이 협력자에 대해 Mock, Stub, Fake 중 어떤 것을 사용하나요?객체지향 코드 테스트
테스트가 시간이나 난수에 의존합니다테스트 용이성 설계
테스트만 접근할 수 있도록 코드가 공개됩니다테스트 용이성 설계
이 코드를 안전하게 재구성하려면 어떻게 해야 하나요?객체 설계로의 리팩토링
리팩토링이 너무 커져서 끝낼 수 없습니다객체 설계로의 리팩토링
테스트가 없는 코드를 변경해야 합니다레거시 코드 작업
오래된 시스템을 조각조각 교체하세요레거시 코드 작업
이 리뷰에서 무엇을 확인해야 하나요?객체 설계 검토
어떤 리뷰 결과가 병합을 차단하나요?객체 설계 검토
아무도 코드가 이렇게 만들어진 이유를 기억하지 못합니다설계 결정 문서화
무엇을 그리고, 어떤 수준으로 그려야 하나요?설계 결정 문서화
주석이 코드를 반복하거나 모순됩니다코드가 말할 수 없는 것에 주석 달기
이 코드가 왜 이상해 보이는지 어디에서 설명하나요?코드가 말할 수 없는 것에 주석 달기
프레임워크 훅이나 마커가 비즈니스 규칙을 보유합니다프레임워크 내 작업
프레임워크를 얼마나 따라가야 하나요?프레임워크 내 작업
계산이 입력을 저장, 전송 또는 변경하기도 합니다함수형 기법 적용
어떤 함수형 기법이 객체 코드에 적합한가요?함수형 기법 적용

언어별 스킬

언어별 스킬은 하나의 언어에 대한 핵심 규칙을 유지하며 결코 이를 대체하지 않습니다. 기본 언어 스킬은 프레임워크가 없는 코드를 위한 것입니다.

  • oo-java, object-oriented-design-java에서: 레코드, 봉인 타입, equals와 hashCode, 확인된 예외, Optional, 확장에 닫힌 클래스.
  • oo-kotlin, object-oriented-design-kotlin에서: 데이터 클래스, 봉인 타입, 널 가능 타입, by를 사용한 위임, 확장 함수.
  • oo-typescript, object-oriented-design-typescript에서: 브랜드 식별자, #private 상태, 추상 클래스, 데코레이터, 판별 유니언, 구성 루트.
  • oo-javascript, object-oriented-design-javascript에서: c

…

[번역을 위해 잘림]

관련 스킬