May 26, 2024
훌륭한 설계
설계, 유지보수를 이야기할 때 이론을 중심에 두는 것은 적절하지 않음
코드
그 자체소극장
초대장이 있다면 티켓을 관람객의 가방에 넣어주고 없다면 티켓을 판매함
모듈
로버트 마틴
모든 소프트웨어 모듈에는 세 가지 목적이 있음
⇒ 모든 모듈은 제대로 실행돼야 하고, 변경이 용이해야 하며, 이해하기 쉬워야 함
이해 가능한 코드
: 그 동작이 예상에서 크게 벗어나지 않는 코드현재의 코드
: 상식과 너무 다르게 동작해 코드를 읽는 사람과 제대로 의사소통하지 못함Theater : 관람객이 가방을 가지며 판매원이 매표소에서만 티켓을 판매한다는 지나치게 세부적인 사실에 의존함
⇒ 객체 사이의 의존성
과 관련된 문제
의존성
객체 사이의 의존성을 완전히 없애는 것이 정답은 아님
객체지향 설계
는 서로 의존하며 협력하는 객체들의 공동체를 구축하는 것결합도
가 높다
두 객체 사이의 결합도가 높을수록 함께 변경될 확률도 높아져 변경하기 어려워짐
⇒ 설계의 목표는 객체 사이의 결합도를 낮춰 변경이 용이한 설계를 만드는 것
해결 방법
: Theater가 Audience와 TicketSeller에 관해 너무 세세한 부분까지 알지 못하도록 정보를 차단
⇒ 관람객과 판매원을 자율적인 존재
로 만들면 됨
설계 변경이 어려운 이유
해결 방법
: Audience와 TicketSeller가 직접 Bag과 TicketOffice를 처리하는 자율적인 존재가 되도록 설계를 변경하는 것
⇒ ticketOffice에 대한 접근은 오직 TicketSeller에서만 존재하게 됨
캡슐화
수정 후
인터페이스(interface)
에만 의존함TicketSeller가 내부에 TicketOffice 인스턴스를 포함하고 있다는 사실은 구현(implementation)
영역에 속함
⇒ 객체를 인터페이스와 구현으로 나누고 인터페이스만을 공개하는 것은 객체 사이의 결합도를 낮추고 변경하기 쉬운 코드를 작성하기 위해 따라야 하는 가장 기본적인 설계 원칙
캡슐화 개선 후 가장 큰 개선점은 Audience와 TicketSeller가 내부 구현을 외부에 노출하지 않고 자신의 문제를 스스로 책임지고 해결한다는 것
⇒ 자율적인 존재가 된 것
수정된 Audience와 TicketSeller는 자신이 가지는 모든 소지품을 스스로 관리함
⇒ 우리의 예상과 정확히 일치함
⇒ 코드의 독자와의 의사소통 관점에서 확실히 개선됨
자기 자신의 문제를 스스로 해결하도록 코드를 변경한 것
⇒ 객체의 자율성을 높이는 방향으로 설계를 개선함
응집도
가 높다
객체의 응집도를 높이려면 객체 스스로 자신의 데이터를 책임져야 함
프로세스와 데이터를 별도의 모듈에 위치시키는 방식
프로세스(Process)
: Theater의 enter 메서드데이터(Data)
: Audience, TicketSeller, Bag, TicketOffice직관에 위배됨 : 관람객과 판매원이 수동적인 존재일 뿐
데이터의 변경으로 인한 영향을 지역적으로 고립시키기 어려움
변경하기 쉬운 설계
절차적 프로그래밍
: 프로세스가 필요한 모든 데이터에 의존해야 하기 때문에 변경에 취약할 수 밖에 없음절차적 프로그래밍 | 객체지향 프로그래밍 |
---|---|
작업 흐름이 주로 Theater에 의해 제어됨 | 제어 흐름이 각 객체에 적절히 분산돼 있음 |
⇒ 책임이 Theater에 집중돼있음 | ⇒ 하나의 기능 완성에 필요한 책임이 여러 객체에 분산됨 |
데이터와 프로세스가 별도의 객체에 위치 | 데이터와 프로세스가 동일한 객체에 위치 |
설계를 어렵게 만드는 것은 의존성
해결 방법: 불필요한 의존성 제거로 객체 사이의 결합도
를 낮추는 것
⇒ 결합도
를 낮추기 위해 캡슐화
사용
개선 후
설계에 대한 사실
의인화
좋은 설계
변경 가능 코드
: 이해하기 쉬운 코드훌륭한 객체지향 설계
: 객체 사이의 의존성을 적절하게 관리하는 설계