객체 설계 하기
- 객체의 책임을 공개 메서드를 통해서 들어낼수 있다.
객체로 추상화 하기
- 비공개 필드 (데이터), 비공개 로직 (코드)
- 공개 메서드 선언부를 통해 외부세계와 소통
- 각메서드의 기능은 객체의 책임을 드러내는 창구
- 객체의 책임이 나뉨에 따라 객체 간 협력이 발생
객체가 제공하는 것
- 절차 지향에서 잘 보이지 않았던 개념을 가시화
- 관심사가 한 군데로 모이기 때문에, 유지보수성이 올라감
- 예시) 객체 내부에서 객체가 가진 데이터의 유효성 검증 책임을 가질 수 있다.
- 여러 객체를 사용하는 입장에서는, 구체적인 구현에 신경 쓰지 않고 보다 높은 추상화 레벨에서 도메인 로직을 다루 수 있다.
새로운 객체를 만들 때 주의할 점
- 1개의 관심사로 명확하게 책임이 정의되었는지 확인
- 메서드를 추상화 할때랑 비슷
- 객체를 만듦으로써 외부 세계와 어떤 소통을 하려고 하는지 생각
- 객체의 책임이나 역할이 요구사항에 변경에 따라 계속 변할수 있으므로 유도리 있게 작성한다.
- 생성자, 정적 팩토리 메서드에서 유효성 검증이 가능하다.
- 도메인에 특화된 검증 로직이 들어갈 수 있다.
- setter 사용 자제(폭력적인 메서드)
- 데이터는 불변이 최고이고 변하는 데이터더라도 객체가 핸들링할 수 있어야 한다.
- 객체 내부에서 외부 세계의 개입 없이 자체적인 변경/가공으로 처리할 수 있는지 확인해야한다.
- 만약 외부에서 가지고 있는 데이터로 요청 해야 하는 경우에는 단순이 set~ 라는 이름보단 update~ 같이 의도를 드러내는 네이밍을 고려하는게 좋다
- getter 도 마찬가지로 사용 자제 하고 반드시 필요한 경우에 추가하는게 좋다
- 외부에서 필요하다고 getter를 남발하는것은 무례한 행동이다
- 객체에 메시지를 보내주자
- 필드의 수는 적을수록 좋다
- 불필요한 데이터가 많을수록 복잡도가 높아지고 대응할 변화가 많아진다.
- 필드 A를 가지고 계산할수 있는 A' 이라는 필드가 있다면, 메서드 기능으로 제공
- 단, 미리 가공하는것이 이점이 있다면 필드로 가공하는것이 좋을수도 있다
SOLID
SRP : Single Responsibility Principle (단일 책임 원칙)
- 하나의 클래스는 한가지의 변경 이유만을 가져야한다.
- 변경이유 = 책임
- 객체가 가진 공개 메서드, 필드, 상수 등은 해당 객체의 단일 책임에 의해서만 변경 되는가?
- 관심사의 분리
- 높은 응집도, 낮은 결합도
OCP: Open-Closed Principle
- 확장에는 열려있고, 수정에는 닫혀 있어야한다
- 기존 코드의 변경 없이, 시스템의 기능을 확장할 수 있어야한다.
- 추상화와 다형성을 활용해서 OCP를 지킬 수 있다.
- 새로운 기능 새로운 요구사항이 추가됐을때 기존 코드의 과도한 변경이 없어야 한다.
LSP: Liskov Substitution Principle
- 상속 구조에서, 부모 클래스의 인스턴스를 자식 클래스의 인스턴스로 치환할 수 있어야 한다.
- 자식 클래스는 부모 클래스의 책임을 준수하며, 부모 클래스의 행동을 변경하지 않아야 한다.
- LSP를 위반하면, 상속 클래스를 사용할 때 오동작 또는 예상 밖의 예외가 발생하거나, 이를 방지하기 위한 불필요한 타입 체크가 동반될 수 있다.
DIP: Dependency Inversion Principle
- 상위 수준의 모듈은 하위 수준의 모듈에 의존해서는 안 된다. 둘 모두 추상화에 의존해야 한다.
- 의존성의 순방향 : 고수준 모듈이 저수준 모듈을 참조하는 것
- 의존성의 역방향 : 고수준, 저수준 모듈이 모두 추상화에 의존하는것
- 저수준 모듈이 변경되어도, 고수준 모듈에는 영향이 가지 않는다.
'인프런 > Readable Code: 읽기 좋은 코드를 작성하는 사고법 리뷰' 카테고리의 다른 글
섹션 3 : 논리, 사고의 흐름 (0) | 2024.11.17 |
---|---|
섹션 2 : 추상(抽象) (1) | 2024.11.17 |