본문 바로가기

이펙티브 자바

[이펙티브 자바] 아이템 16. public 클래스에서는 public 필드가 아닌 접근자 메서드를 사용하라

캡슐화는 객체의 데이터(필드)와 그 데이터를 조작하는 메서드를 하나의 단위로 묶는 것을 의미한다. 이를 통해 객체의 상태를 보호하고 외부에서 직접 접근하는 것을 제한하여 객체의 유지보수와 확장성을 향상시킬 수 있다.

// 좋지 않은 예: public 필드를 직접 사용
class PersonBadExample {
    public String name;
    public int age;

    public PersonBadExample(String name, int age) {
        this.name = name;
        this.age = age;
    }
}

// 좋은 예: private 필드와 public 접근자/설정자 메서드를 사용
class PersonGoodExample {
    private String name;
    private int age;

    public PersonGoodExample(String name, int age) {
        this.name = name;
        this.age = age;
    }

    // 이름에 대한 접근자 메서드
    public String getName() {
        return name;
    }

    // 이름을 설정하는 메서드
    public void setName(String name) {
        this.name = name;
    }

    // 나이에 대한 접근자 메서드
    public int getAge() {
        return age;
    }

    // 나이를 설정하는 메서드
    public void setAge(int age) {
        if (age > 0) { // 유효성 검사 예시
            this.age = age;
        }
    }
}

// 사용 예
public class Main {
    public static void main(String[] args) {
        // 좋지 않은 예
        PersonBadExample badExample = new PersonBadExample("John Doe", 30);
        badExample.age = -5; // 유효하지 않은 나이 설정 가능
        
        // 좋은 예
        PersonGoodExample goodExample = new PersonGoodExample("Jane Doe", 30);
        goodExample.setAge(-5); // 유효성 검사를 통과하지 못해 설정되지 않음
    }
}

 

좋지 않은 예에서는 필드를 public 으로 설정해 객체의 상태를 외부에서 직접 변경할 수 있게 되어있다. 이는 잘못된 설계이다.

좋은 예 에서는 모든 필드를 private로 선언해 각 필드에 대한 접근자(getter)와 설정자(setter)메서드를 제공해주어 내부 표현 방식을 언제든 바꿀 수 있는 유연성을 얻을 수 있다.

 

결론 : public 클래스는 절대 가변 필드를 노출해서는 안된다. 불변 필드라면 노출해더 덜 위험하지만 안전한것은 아니다. 하지만 package-private 클래스나 private 중첩 클래스에서는 종종 필드를 노출하는 편이 나을때도 있다.