객체지향에서 중요한 건 “데이터를 들고 있다”가 아니라, 그 데이터를 바탕으로 무슨 일을 할 수 있느냐입니다.
이때 객체가 제공하는 행동이 바로 메서드입니다.
같은 데이터라도, 어떤 메서드를 통해 다루느냐에 따라 규칙(불변 조건)을 지킬 수도 있고, 깨뜨릴 수도 있습니다. 그래서 실무에서 메서드는 단순 함수가 아니라 도메인 규칙을 지키는 “게이트” 역할을 합니다.
“객체의 가치는 상태가 아니라,
상태를 안전하게 다루는 행동(메서드)에 있다.”
좋은 객체지향 설계는 “필드(데이터) + 메서드(행동)”의 조합이 자연스럽습니다. 외부에서 상태를 직접 바꾸지 못하게 하고, 의미 있는 행동을 통해서만 상태가 변하도록 만들면 객체가 스스로 규칙을 지키게 됩니다.
👍 GOOD (행동 중심)
- 메서드 이름이 “무슨 일”을 하는지 드러냄 (ex. withdraw, cancel, approve)
- 상태 변경은 메서드 내부에서 검증 후 수행
- 객체 스스로 불변 조건을 지킴
- 호출자는 “어떻게”가 아니라 “무엇을” 요청
👎 BAD (데이터 중심)
- getter/setter로 외부가 상태를 마음대로 변경
- 메서드는 없고 “데이터만 담는 객체(빈 껍데기)”가 많아짐
- 검증 로직이 서비스/컨트롤러에 흩어져 규칙이 깨짐
- if/switch로 상태를 매번 검사하면서 분기
// 예시: 계좌(Account)의 상태(balance)를 외부에서 직접 못 바꾸게 하고 // "입금/출금"이라는 의미 있는 행동(메서드)으로만 변경하게 만든다. class Account { private int balance; public Account(int initial) { if (initial < 0) throw new IllegalArgumentException("balance must be >= 0"); this.balance = initial; } // 행동 1) 입금: 규칙을 통과한 경우에만 상태 변화 public void deposit(int amount) { if (amount <= 0) throw new IllegalArgumentException("amount must be > 0"); this.balance += amount; } // 행동 2) 출금: 잔액 부족이면 실패(불변 조건 유지) public void withdraw(int amount) { if (amount <= 0) throw new IllegalArgumentException("amount must be > 0"); if (this.balance < amount) throw new IllegalStateException("insufficient balance"); this.balance -= amount; } // 읽기만 제공(상태 변경은 불가) public int balance() { return balance; } } // 핵심: 메서드가 "상태 변경 경로"를 통제하면서 규칙을 강제한다.
💡 TIP / 참고사항
메서드를 만들 때 가장 좋은 기준은 “필드를 노출하지 않고도 이 기능이 가능한가?” 입니다.
getter로 꺼내서 밖에서 계산하는 순간, 규칙이 객체 밖으로 새어 나갑니다. 가능하면 계산/검증/변경을 객체 안의 메서드로 넣어 “규칙을 한 곳에” 모으세요.
✅ 핵심 요약
- ✔️ 행동(메서드)은 객체가 수행하는 동작이며, 상태를 바꾸거나 결과를 반환한다.
- ✔️ 메서드는 상태 변경 경로를 통제해 규칙(불변 조건)을 지키는 “게이트” 역할을 한다.
- ✔️ 좋은 메서드는 행위가 드러나는 이름을 가지며, 호출자가 내부 구현을 몰라도 사용 가능하다.