'자율적인' 객체란 무엇일까?
객체는 스스로 정한 원칙에 따라 판단하고, 스스로의 의지로 행동하는 존재다.
하지만, 객체가 행동하는 진짜 이유는 하나다.
다른 객체로부터 요청을 받았기 때문이다.
요청을 받아서 행동하는 것,
그 행동을 우리는 **"책임"**이라고 부른다.
즉, 자율적인 객체란, 요청을 받더라도 스스로 판단해서 책임을 수행하는 객체를 말한다.
요청은 구체적이어도, 추상적이어도 문제다
자율성을 살리려면 요청을 너무 구체적으로 하면 안 된다.
예를 들어,
"아이스 바닐라 라떼를 만들어 주세요. 얼음은 50g, 커피와 우유 비율은 9:1로 해주세요."
이렇게 지나치게 세세한 요청을 하면,
바리스타 객체는 스스로 판단할 여지가 없다.
단순히 지시받은 대로 만들 뿐이다. (자율성 X)
반대로,
"커피 하나 주세요."
처럼 너무 추상적이면,
캐셔는 얼마를 받아야 할지,
바리스타는 어떤 커피를 만들지 모른다.
협력 자체가 엉킨다.
요청은 적당히.
"무엇을 원하는지만 분명히 하고, "어떻게"는 맡기는 게 좋다.
좋은 요청: "아이스 바닐라 라떼 한 잔 부탁해요."
이 정도가 딱 좋다.
메시지 전송
객체의 행동을 유발시키는 행위.
구조:
수신자 객체.메시지 이름(인자1, 인자2)
Ex) 바리스타.바닐라_라떼(아이스, 설탕X)
메시지와 메서드의 관계
- 메시지: "무엇"을 해야 할지 요청한다.
- 메서드: "어떻게" 처리할지 객체가 스스로 선택한다.
객체는 메시지를 받으면, 그에 대응하는 메서드를 골라 실행한다.
다형성(Polymorphism)이란?
서로 다른 타입의 객체들이, 동일한 메시지를 받았을 때, 서로 다른 방식으로 처리하는 능력.
쉽게 말해, 같은 요청을 다르게 해석하는 능력이다.
왜 가능할까?
객체가 자율적으로 책임을 수행하기 때문이다.
하나의 메시지 ↔ 다수의 메서드 (같은 요청, 다양한 대응)
다형성이 만족되면?
- 같은 책임을 공유하고
- 같은 역할을 수행할 수 있고
- 서로 대체 가능하다
그래서,
시스템은 더 유연해지고, 객체는 더 많이 재사용될 수 있다.
다형성이 만들어내는 유연한 협력
1. 송신자는 수신자의 타입을 신경 쓸 필요가 없다
메시지를 이해할 수 있는 객체라면 누구든 협력할 수 있다.
(= 수신자가 쉽게 바뀔 수 있다.)
2. 협력 방식을 쉽게 확장할 수 있다
새로운 타입의 객체를 추가해도 기존 협력 구조를 깨지 않는다.
3. 협력 구조 자체를 재사용할 수 있다
(Ex) 음식 주문
- 카페: 손님 → 바리스타
- 레스토랑: 손님 → 쉐프
다형성이 가능한 이유: 메시지 중심 설계
송신자: "나는 이 메시지를 보낼 거야. 누가 받든 상관없어."
수신자: "내가 이 메시지를 이해하고 처리할게."
이렇게 서로 타입이나 내부를 신경쓰지 않는다.
= 느슨한 연결(Loose Coupling)
책임-주도 설계 방법
1단계. 시스템의 주요 기능을 "책임"으로 식별하고, 담당 객체를 정한다.
(ex. "주문 처리" → 캐셔 객체)
2단계. 다른 객체의 도움이 필요하면 요청할 메시지를 정의한다.
(ex. 캐셔 → "결제는 할 수 있는데, 음료는 못 만들어...")
3단계. 수신자(누구)를 선택한다.
(ex. "아이스 바닐라 라떼" 요청 → 바리스타에게)
4단계. 필요한 만큼 2~3단계를 반복한다.
주의사항
1. 객체의 상태를 묻지 말 것
상태를 묻으면 불필요한 의존이 생긴다.
2. '어떻게'가 아닌 '무엇'을 요청할 것
방법을 지시하지 말고, 결과만 요청해야 자율성이 유지된다.
3. '무엇' 중심 요청은 인터페이스를 작게 만든다
"어떻게"를 지시하지 않으면, 외부에 공개해야 할 동작이 줄어들어 인터페이스가 작아진다.
인터페이스가 작아지면 결합도가 낮아지고, 설계가 유연해진다.
인터페이스란 무엇인가?
두 사물이 마주치는 경계 지점에서 서로 상호작용할 수 있게 해주는 장치.
인터페이스의 특징
- 사용법만 알면 내부 구조를 몰라도 된다.
- 내부 구조는 바꿔도 인터페이스만 유지하면 문제없다.
- 대상이 달라도 같은 인터페이스면 상호작용할 수 있다.
예시
- 리모컨
- ATM 기계
- USB-C 충전 케이블
객체 관점에서 보는 인터페이스
객체가 받을 수 있는 메시지의 목록이 객체의 인터페이스다.
- 인터페이스만 알면 내부를 몰라도 소통할 수 있다.
- 인터페이스만 유지되면 내부 변경은 외부에 영향을 주지 않는다.
- 같은 인터페이스라면 다른 객체로 대체해도 문제없다.
메시지가 인터페이스를 결정한다
객체는 오직 메시지를 통해 상호작용한다.
어떤 메시지를 수신할 수 있느냐가 객체의 인터페이스를 만든다.
공용 인터페이스 vs 사적 인터페이스
- 공용 인터페이스: 외부에 공개 (ex. 주문 받기)
- 사적 인터페이스: 내부용 (ex. 재고 확인)
자기 자신과의 상호작용도 메시지로 해야 한다.
(예: 바리스타가 커피 만들기 전, 재료 체크)
좋은 인터페이스 설계 3원칙 (by 맷 와이스펠드)
- 추상적인 수준에서 메시지 설계 (자율성 보장)
- 최소한의 공용 인터페이스
(인터페이스를 최소로 유지하면 객체의 내부 동작에 대해 가능한 한 적은 정보만 외부에 노출.
객체의 내부를 수정 시, 외부에 미치는 영향을 최소화) - 인터페이스와 구현을 명확히 구분 (변경에 강한 설계)
구현이란?
공용 인터페이스에 포함되지 않는 모든 내부 상태와 행동을 의미한다.
(ex. 상태-property, 행동-method)
인터페이스와 구현을 분리하는 이유
내부 구현과 외부 인터페이스가 섞이면, 작은 변경도 시스템 전체에 영향을 준다.
구현과 인터페이스를 분리하면,
- 내부는 자유롭게 수정 가능하고
- 외부 객체는 안정적으로 동작할 수 있다. [ 공용 인터페이스만 수정하지 않는다면 ]
결국 시스템은 변경에 강하고, 유지보수가 쉬워진다.
캡슐화와 자율성
캡슐화란, 객체의 내부 상태와 행동을 숨기는 것이다.
캡슐화를 통해
- 스스로 상태를 관리하고
- 외부 간섭 없이 변할 수 있다.
결과적으로
객체는 자율성을 확보하고,
변경에도 강해지고,
협력은 깔끔해진다.
상태와 행위의 캡슐화
객체는 상태와 행동을 하나로 묶어 독립적인 단위를 이룬다.
외부에는 꼭 필요한 행동만 공개하고 나머지는 감춘다.
데이터 캡슐화는 인터페이스와 구현 분리, 자율성 확보의 전제 조건이다.
사적인 비밀의 캡슐화
외부가 객체의 내부를 직접 관찰하거나 제어하지 못하게 막아야 한다.
변경이 잦은 세부사항은 안정적인 인터페이스 뒤로 숨긴다.
이렇게 사적인 비밀을 보호해야
객체는 유연하고 재사용 가능한 형태를 유지할 수 있다.
책임의 자율성이 협력의 품질을 결정한다
1. 협력을 단순하게 만든다
자율적인 책임은 세부 사항 대신 의도만 드러내기 때문에, 협력이 단순하고 명확해진다.
(= 책임이 적절하게 추상화된다.)
2. 외부와 내부를 명확히 분리한다
책임을 자율적으로 수행하면, 송신자가 수신자의 내부를 몰라도 협력할 수 있다.
(= 캡슐화)
3. 내부 변경이 외부에 영향을 주지 않는다
수신자가 책임 수행 방식을 바꿔도, 인터페이스만 유지되면 협력에는 영향이 없다.
(= 결합도가 낮아진다.)
4. 협력 대상을 유연하게 선택할 수 있다
메시지를 이해하는 객체라면 누구나 수신자가 될 수 있어, 확장성과 재사용성이 높아진다.
(= 설계가 유연해진다.)
5. 객체의 역할을 이해하기 쉬워진다
자율적 책임은 객체의 존재 이유를 명확히 드러내며,
객체는 동일한 목적을 달성하는 강하게 연관된 책임들로 구성된다.
(= 응집도가 높아진다.)
※ 본 글은 『객체지향의 사실과 오해』(조영호 저) 5장을 기반으로 학습 목적으로 요약한 글입니다.
※ 이 글은 책의 내용을 요약한 것으로, 원문 없이 읽을 경우 오해의 여지가 있을 수 있습니다. 정확한 이해를 위해 원서의 정독을 권장합니다.
'개발 관련 지식' 카테고리의 다른 글
객체지향의 사실과 오해 정리 - 7장. 역할, 책임, 협력 관점에서 본 객체지향 (0) | 2025.05.06 |
---|---|
객체지향의 사실과 오해 정리 - 6장. 객체 지도 (0) | 2025.05.03 |
객체지향의 사실과 오해 정리 - 4장. 역할, 책임, 협력 (0) | 2025.04.23 |
객체지향의 사실과 오해 정리 - 3장. 타입과 추상화 (0) | 2025.04.21 |
객체지향의 사실과 오해 정리 - 2장. 이상한 나라의 객체 (0) | 2025.04.19 |