개발을 하다 보면, "내가 만든 코드가 유지보수하기 좋고, 다른 사람이 봐도 쉽게 이해할 수 있을까?"라는 고민을 하게 됩니다.
이럴 때 객체지향 프로그래밍(OOP)의 캡슐화(Encapsulation) 개념이 큰 도움이 됩니다.
캡슐화는 객체 내부의 데이터(필드)와 이를 조작하는 메서드를 하나로 묶고, 외부에서 직접 접근하지 못하도록 막는 것입니다.
쉽게 말해, "내부 속은 감추고, 필요한 것만 딱 보여주자!"라는 개념입니다.
만약 객체 내부 데이터를 마음대로 수정할 수 있다면, 내가 만든 클래스가 여기저기에서 예측하지 못한 방식으로 사용될 수 있다.
그러다 보면 "이거 고치면 저기도 터지고, 저거 고치면 여기도 문제 생기고..." 하는 수정 지옥에 빠질 수도 있다.
캡슐화하면 내부 구현을 보호하면서, 외부에는 필요한 기능만 제공하기 때문에 변경이 더 쉬워진다.
내가 만든 클래스를 다른 개발자들이 사용할 수도 있다. 예를 들어 나이를 반환하는 메서드를 사용할 수 있게 하는 것이다.
근데 만약 나이 반환 함수의 이름이 바뀌거나 리턴값이 바뀐다면?
이런 이상한 값들이 저장되지 않도록 보호하는 게 바로 캡슐화의 역할이다.
많은 사람들이 "캡슐화를 하려면 Getter/Setter를 쓰면 되잖아?"라고 생각하는데, Setter를 무조건 만드는 것도 문제다.
class User {
public String username;
public String password;
}
public class Main {
public static void main(String[] args) {
User user = new User();
user.username = "admin"; // 아무렇게나 변경 가능
user.password = "1234"; // ❌ 보안상 위험!
System.out.println("사용자명: " + user.username);
System.out.println("비밀번호: " + user.password);
}
}
✔ 문제점
username
, password
가 public
이므로 외부에서 아무렇게나 변경 가능 class User {
private String username;
private String password;
// 생성자로 ID 설정 (외부에서 수정 불가능)
public User(String username, String password) {
this.username = username;
setPassword(password); // 비밀번호는 검증 후 설정
}
// Getter (읽기 전용)
public String getUsername() {
return username;
}
public String getPassword() {
return "보안상 비밀번호는 직접 제공되지 않습니다.";
}
// Setter는 최소한으로! (비밀번호 변경 시 검증)
public void setPassword(String password) {
if (password.length() >= 8) {
this.password = password;
} else {
System.out.println("❌ 비밀번호는 최소 8자 이상이어야 합니다.");
}
}
}
public class Main {
public static void main(String[] args) {
User user = new User("admin", "securePass");
user.setPassword("1234"); // ❌ 비밀번호 너무 짧음 → 설정 거부
System.out.println("사용자명: " + user.getUsername());
System.out.println("비밀번호: " + user.getPassword()); // ✅ 직접 출력 불가
}
}
✔ 개선된 점
username
은 생성자로 한 번만 설정하고, 이후 외부에서 변경 불가능 setPassword()
에 비밀번호 검증 로직을 추가하여 보안 강화 getPassword()
에서 비밀번호를 직접 노출하지 않도록 처리 Setter는 꼭 필요한 경우에만 만들고, 데이터 무결성을 지키는 로직을 추가해야 한다!
✔ 필드는 기본적으로 private
으로 설정하자!
✔ Setter를 무조건 만들지 말고, 정말 필요한 경우만 제공하자!
✔ Setter를 사용할 때는 값 검증 로직을 추가하자!
✔ Getter에서도 중요한 정보는 그대로 반환하지 말고, 적절한 가공을 하자!
프로그래밍을 하다 보면, 동료에게
"아, 이 변수를 바꾸셔서 오류가 생겨요."
"값을 입력하는 방식을 바꾸셔서 문제가 생겨요!"
라는 순간이 온다.
그럴 때 "캡슐화를 조금만 더 고려했다면..." 이라 생각하게 된다...
캡슐화는 나중에 코드가 꼬이지 않게 보호해주는 안전장치 같은 역할을 한다.
즉, 핵심은?
"내부는 보호하고, 외부에는 꼭 필요한 기능만 확실하게 제공하자!"
✅ 캡슐화는 객체 내부의 데이터를 보호하는 것!
✅ 무분별한 Setter 사용은 오히려 객체의 안정성을 해칠 수 있음!
✅ 필요한 기능만 외부에 제공하고, 내부 구현은 감추자!