Item16. Accessor Methods Over Public Fields
Public 클래스에서는 public 필드가 아닌 접근자 메서드를 사용하라
자바에서의 클래스 설계 시, 객체 지향 원칙을 준수하는 것이 중요합니다. 이 원칙 중 하나는 클래스의 상태를 외부에 노출하지 않고, 접근자 메서드를 통해 접근하게 하는 것입니다. 이러한 설계는 클래스의 유연성을 높이고, 유지보수성을 향상시킵니다.
1. Public 필드의 문제점
클래스의 필드를 public으로 선언하게 되면, 그 필드에 직접 접근이 가능합니다. 이 방법은 코드 작성이 간단하고, 초기 학습 단계에서는 매력적으로 보일 수 있습니다. 하지만, 이 방식에는 다음과 같은 문제점들이 존재합니다:
캡슐화의 위반: 객체 지향 프로그래밍에서 중요한 원칙 중 하나인 캡슐화(encapsulation)는 객체의 상태를 외부에서 직접 변경하지 못하도록 보호하는 것입니다. 그러나 필드가 public으로 선언되면, 외부에서 직접 해당 필드를 조작할 수 있어 객체의 상태가 불안정해질 수 있습니다. 이로 인해 버그가 발생할 가능성이 높아집니다.
변경에 취약: public 필드를 사용하는 경우, 해당 필드를 사용하는 모든 코드가 그 필드의 내부 구조에 의존하게 됩니다. 이로 인해 필드의 타입이나 의미를 변경하려면 그 필드를 참조하는 모든 코드를 수정해야 합니다. 반면, 접근자 메서드를 사용하면 메서드 내부에서 필드에 대한 변경 사항을 감출 수 있습니다.
불변성을 보장하기 어려움: 불변 객체는 다중 스레드 환경에서 안전하게 사용할 수 있어 자바에서 중요한 개념입니다. 하지만 public 필드를 사용하면 객체의 불변성을 보장하기 어렵습니다. 필드를 public으로 노출하면, 외부에서 해당 필드를 변경할 수 있기 때문에, 객체의 상태가 변하게 됩니다.
2. 접근자 메서드를 사용해야 하는 이유
접근자 메서드를 사용하면, 객체의 내부 구현을 숨기고 외부와의 상호작용을 제어할 수 있습니다. 다음은 접근자 메서드를 사용해야 하는 몇 가지 주요 이유입니다:
캡슐화: 필드를 private으로 선언하고, 접근자(getter)와 설정자(setter) 메서드를 제공하면, 클래스 외부에서는 이 필드에 직접 접근할 수 없습니다. 이로 인해 클래스의 내부 구현이 외부로부터 보호됩니다.
유연성: 접근자 메서드를 사용하면, 필드의 값이 읽히거나 쓰일 때 추가적인 로직을 삽입할 수 있습니다. 예를 들어, 값을 읽을 때 캐싱을 사용하거나, 값을 설정할 때 유효성 검사를 추가할 수 있습니다.
불변성 강화: 클래스의 필드를 final로 선언하고, 생성자에서만 초기화하게 하면, 해당 클래스는 불변 객체가 됩니다. 이는 다중 스레드 환경에서 안전성을 제공합니다.
인터페이스와의 일관성: 접근자 메서드를 사용하면, 클래스의 필드를 외부에 공개하지 않고도 인터페이스를 통해 일관된 방법으로 접근할 수 있습니다. 이는 코드의 가독성과 유지보수성을 높이는 데 도움이 됩니다.
3. 불변 클래스의 설계
불변 클래스는 객체가 생성된 이후 그 상태를 변경할 수 없는 클래스를 의미합니다. 이러한 클래스는 다중 스레드 환경에서 안전하게 사용될 수 있어, 자바에서 특히 중요합니다. 불변 클래스를 설계할 때 접근자 메서드를 사용하는 것은 필수적입니다.
4. Lombok을 사용한 접근자 메서드 자동 생성
자바에서 접근자 메서드를 수동으로 작성하는 것은 반복적이고 번거로울 수 있습니다. 이럴 때, Lombok 라이브러리를 사용하면 접근자 메서드를 자동으로 생성할 수 있습니다. Lombok을 사용하면 코드가 간결해지고, 유지보수성이 향상됩니다.
6. 캡슐화와 정보 은닉의 중요성
캡슐화(encapsulation)와 정보 은닉(information hiding)은 객체 지향 프로그래밍의 핵심 개념으로, 클래스 설계에서 중요한 역할을 합니다. 이 두 개념은 클래스 내부의 구현 세부 사항을 외부로부터 숨기고, 외부와의 상호작용을 제한함으로써 코드의 안정성과 유지보수성을 높이는 데 기여합니다.
public 필드를 사용하는 것은 캡슐화와 정보 은닉의 원칙을 위반하는 행위입니다. 반면, 접근자 메서드를 통해 필드에 접근하도록 설계하면, 클래스 내부의 구현을 보호할 수 있습니다.
7. 접근자 메서드의 유효성 검사 및 추가 로직
접근자 메서드를 사용하는 또 다른 중요한 이유는 필드 값에 대한 유효성 검사와 추가 로직을 적용할 수 있다는 점입니다. 필드에 직접 접근하면 이러한 로직을 적용할 수 있는 기회가 사라지지만, 접근자 메서드를 사용하면 필요에 따라 다양한 검사를 추가할 수 있습니다.
8. 접근자 메서드와 객체 직렬화
객체 직렬화는 객체의 상태를 저장하거나 네트워크를 통해 전송할 때 사용됩니다. 자바에서는 Serializable
인터페이스를 사용하여 객체를 직렬화할 수 있습니다. 하지만, 직렬화 가능한 객체의 필드를 public으로 선언하는 것은 위험할 수 있습니다. 필드가 외부에 노출되면 객체의 내부 구현이 고정되어 버리기 때문에, 향후 변경이 어려워집니다.
9. 접근자 메서드의 성능 고려사항
일부 개발자들은 성능상의 이유로 필드를 public으로 선언하기도 합니다. 접근자 메서드를 호출하는 것보다 필드에 직접 접근하는 것이 더 빠르다고 생각할 수 있기 때문입니다. 하지만, 현대의 자바 컴파일러와 JIT(Just-In-Time) 컴파일러는 이러한 차이를 최소화하며, 실제로는 접근자 메서드를 사용하는 것이 더 안전하고 권장됩니다.
성능 최적화와 접근자 메서드
실제 애플리케이션에서 성능 문제가 발생하는 경우는 드뭅니다. 대부분의 경우, 접근자 메서드를 사용하는 것이 성능에 미치는 영향은 미미하며, 코드의 가독성과 유지보수성을 높이는 데 더 큰 이점을 제공합니다. 따라서 성능 최적화보다는 안전성과 유연성을 우선시하는 것이 좋습니다.
Last updated