Java 패키지 - 캡슐화
캡슐화은 객체 지향 프로그래밍에서 중요한 특징이다. 데이터를 처리하는 메소드와 여러 데이터들을 하나로 묶어 외부에서 무분별한 접근을 제한한다. 즉, 캡슐화로 데이터를 직접적으로 변경하거나 제한하여 필요한 기능만 제공해주도록 한다.
실제 코드에서도 클래스를 선언하고 그 안에서 데이터와 기능을 묶어 캡슐화하였고, 캡슐화를 안전하게 제공해주는 접근 제어자 또한 알아보았다.
캡슐화에서 외부 노출 대상은?
데이터
객체는 데이터와 기능으로 이루어진다. 이러한 객체를 캡슐화 시 우선으로 숨겨야하는 것이 데이터이다. 객체 외부로 접근해서 데이터를 조작하면 데이터를 다루었던 모든 로직을 무시하고 데이터를 변경한다. 결국 데이터는 안전하지 않게 되고, 캡슐화가 무너진다.
실제 자동차를 운전 시 부품을 모두 열어 데이터를 조작하지 않는다. 자동차의 기능 중 하나인 엑셀을 밟게 되면 자동차가 알아서 가속과 관련된 데이터를 움직여 나아가게 한다.
객체의 데이터는 메소드를 통해 접근해야 하므로 객체 지향 프로그래밍에서 데이터는 모두 숨기는 것이 바람직 하다.
기능
객체에서 제공해야하는 기능 중 외부에서 사용하지 않고 내부에서만 사용하는 기능들이 있다. 이러한 기능은 숨기는 것이 바람직하다.
자동차가 제공하는 엔진 조절, 배기 활동까지 알 필요가 없기에 이러한 기능을 숨기고 사용자에게 제공하는 핸들, 엑셀, 브레이크 정도로 오픈하는 것이 좋다.
사용자에게 엔진 조절과 배기 활동까지 조절해야 자동차가 움직인다면 사용자 입장에서 너무 많은 것을 알아야 자동차를 운전할 수 있다. 단순화해서 핸들, 엑셀, 브레이크 등등 기능만 알려주고 자동으로 엔진과 배기가 조절한다.
필요한 기능만 알리고, 그 외 기능들은 숨겨주도록 한다.
캡슐화 예제
잔고 관리하는 계좌를 만들어 보도록 한다.
BankAccount.java
package access.foo;
public class BankAccount {
private int balance;
// 잔금
public BankAccount() {
this.balance = 0;
}
// 입금
public void deposit(int amount) {
if (isAmountValid(amount)) {
this.balance += amount;
} else {
System.out.println("입력한 금액이 잘못되었습니다.");
}
}
// 출금
public void withdraw(int amount) {
if (isAmountValid(amount) && this.balance >= amount) {
balance -= amount;
} else {
System.out.println("잔액이 부족합니다.");
}
}
public int getBalance() {
return balance;
}
private boolean isAmountValid(int amount) {
// 금액이 0보다 커야함
return amount > 0;
}
}
Bank.java
package access.foo;
public class Bank {
public static void main(String[] args) {
BankAccount account = new BankAccount();
account.deposit(1000);
account.withdraw(700);
System.out.println("balance: " + account.getBalance());
}
}
출력
balance: 300
캡슐화 예제로 사용한 계좌 코드는 다음과 같이 기능을 갖고 있다.
private
- balance 필드: 외부 직접 데이터를 호출하지 않고 있다. private 설정으로 BaknkAccount 클래스 메소드로 통해서만 데이터를 접근할 수 있다.
- isAmountValid() 메소드: 입력 금액을 검증하는 로직. 내부에서만 사용하는 메소드로 private 으로 선언하였다.
public
- deposit(): 입금
- withdraw(): 출금
- getBalance(): 잔고 확인
만약 isAmountValid 를 public 으로 설정한 경우 BankAccount 선언 후 Dot(.) 접근으로 불려올 수 있는 메소드와 데이터를 확인할 수 있는데, isAmountValid를 개발자가 발견한 경우 외부에서 검증해야하는가? 하는 혼동이 발생될 수 있다.
데이터 필드인 balance 까지 public 으로 설정되어 있는 경우 혼란은 가중된다. 개발자가 외부에서 직접 데이터를 넣어야 할지 말아야 할지 복잡성이 커진다.
접근 제어자와 캡슐화로 데이터를 안전하게 보호하고, BackAccount 클래스를 사용하는 개발자 입장에서도 복잡성을 낮추도록 한다.