[Java] 캡슐화

2025. 10. 16. 18:50Dev./Java

728x90
반응형

캡슐화

객체의 상태(필드)를 숨기고(보호) 공개된 메서드로만 접근하게 해서 내부 구현을 바꾸더라도 외부에 영향이 없게 만드는 설계 원칙

캡슐화의 목적

 

  • 데이터 보호: 필드를 private으로 숨겨 잘못된 접근(무결성 훼손)을 막음
  • 인터페이스와 구현 분리: 외부는 무엇을 할 수 있는지(메서드)만 알고, 내부 구현은 바꿀 수 있음
  • 유지보수성 향상: 내부를 바꿔도 외부 코드는 그대로 작동
  • 응집도 증가 / 결합도 감소: 책임이 분명해지고 모듈화가 쉬워짐
  • 검증/비즈니스 로직 중앙화: 값 유효성 검사, 상태 변화 규칙을 한곳(setter/메서드)에 모을 수 있음

적용 예제

1. 필드를 private으로 선언

  • 내부 속성은 private으로 숨기고, 외부는 public 메서드를 통해 접근하게 함
private int result;
private ArrayList<Integer> results = new ArrayList<>();

 

2. 공개 API는 public 메서드로 제공 (getter/setter, 동작 메서드)

  • 필요한 경우만 getter/setter를 제공

3. 불변(Immutable) 디자인 고려

  • 생성 시 값이 정해지고 바뀌지 않아야 하면 final 필드 + no setter

        예시 ) public final class Money { private final int amount; ... }

4.컬렉션 반환 시 방어적 복사 또는 읽기 전용 뷰

//내부 메소드
public class Calculator {
    private ArrayList<Integer> results = new ArrayList<>();

    public ArrayList<Integer> getResults() {
        return results; // 내부 데이터 그대로 반환
    }
}


//외부 클래스
Calculator c = new Calculator();
ArrayList<Integer> history = c.getResults();
history.add(999);  // 외부에서 마음대로 수정이 가능한 상태

이 코드에선 getResults()가 내부 리스트를 그대로 리턴해주기 때문에 외부에서 add, remove, clear 같은 직접적으로 데이터 셋이 가능한 메소드 호출하면 Calculator 내부데이터가 바뀐다. 즉 외부 코드가 내부 상태 값을 건드리면서 캡슐화가 깨짐

  • 방어적 복사
    • 원본은 숨겨두고 외부에는 사본을 넘겨줌 ( 복사본 반환)
public ArrayList<Integer> getResults() {
    return new ArrayList<>(results); //  복사본 반환
}

//외부 클래스
ArrayList<Integer> history = c.getResults();
history.add(999);

history는 복사본이기 때문에 내부의 results 값에는 전혀 영향이 없다.

  • 읽기 전용 뷰로 반환해서 수정 자체를 막음
//내부
public List<Integer> getResults() {
    return Collections.unmodifiableList(results); //  읽기 전용 뷰
}

// 외부 클래스
List<Integer> history = c.getResults();
history.add(999);  //  예외 발생: java.lang.UnsupportedOperationException

읽기만 가능하고 수정 불가능한 뷰 자체를 넘겨줘서 내부 results 값에는 전혀 영향이 없다.

 

설계시 체크리스트

  1. 모든 필드를 public으로 두지 않았는가?
  2. 무결성이 필요한 부분은 private인가?
  3. 외부에 꼭 필요한 getter만 제공하는가?
  4. setter는 최소한으로, 검증 로직 포함인가?
  5. 컬렉션/가변 객체는 복사본 또는 읽기 전용 뷰로 노출하는가?
  6. 클래스 책임이 명확한가 (SRP)?
  7. 클래스 고유 책임에 맞는 곳에서 내부 상태 변경이 이루어 지는가?

SRP(단일 책임 원칙) - 각각의 클래스는 한가지 책임만 가져야 한다. ( 계산기 클래스가 연산+ 사용자 관리+ 통신 전부? X)

728x90
반응형