잘 설계된 모듈과 그렇지 못한 모듈을 구분 짓는 가장 중요한 속성은 바로 구현된 세부사항을 얼마나 잘 감추었는지를 통해 확인할 수 있다.
정보은닉을 통해 서로 API를 통해서만 이용하며, 뒤에서 동작 방식은 상관하지 않기 때문에
의존성이 낮아져 병렬적으로 개발할 수 있기 때문에 유지보수의 부담감과 다른 모듈에 영향을 끼치는 부분이 줄어들게 된다.
자바의 정보은닉 원칙은 단순하다. 각 클래스와 멤버는 가능한 한 접근 불가능하도록 만드는 것.
Public을 부여하는 경우에는 전역적 객체가 되고, 아무런 접근 권한을 부여하지 않으면 package-private로 내부 패키지 접근만 가능하다.
자세한 접근 권한 규칙은 다음과 같다
Private : 클래스 내부에서만 접근이 가능하다.
Package-private : 이렇게 선언된 멤버는 같은 패키지내에서 접근이 가능
Protected : 하위 클래스와 선언된 클래스에서 접근이 가능
Public : 어디서나 사용이 가능
접근 지시자 부여 시 주의 사항
- 객체의 멤버 변수를 절대 public으로 선언하지 마라
Public으로 선언하게 되면 해당 객체의 변수에 직접 접근하여 값을 변경할 수 있으며, 해당 값이 변경 될 때 특정한 동작을 실행하도록 할 수 없기 때문에 다중 스레드에서 문제가 발생할 수 있다.
- 어떤 상수 값들에 대해서 public static final 필드로 선언하여 공개해야 하는 경우가 있다. 이런 필드들은 반드시 변경 불가능 객체를 참조 해야 한다.
하지만 길이가 0이 아닌 배열은 언제나 변경이 가능하므로 public static final 배열 필드를 두거나, 배열 필드를 반환하는 접근자를 정의하면 안 된다.
예를 들면
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | package effectivejava13; public class Test { public static final String[] TEST_ARRAY = new String[] {"test", "test1"}; } package effectivejava13; public class Main { public static void main(String args[]) { Test.TEST_ARRAY[0] = "zz"; for (int i = 0; i < Test.TEST_ARRAY.length; i ++ ) { System.out.println(Test.TEST_ARRAY[i]); } } } 결과 : zz test | cs |
해결 방안 1.
실제 배열은 private로 변경하고, 변경불가능한 list를 만들어 접근하게 진행
1 2 3 | private static final String[] TEST_ARRAY = new String[] {"test", "test1"}; Public static final List<String> VALUES = Collection.unmodifiableList(Arrays.asList(TEST_ARRAY)); | cs |
해결방안 2.
배열을 private로 선언하고 해댱 배열을 복사해서 반환하는 메서드 생성
1 2 3 4 | private static final String[] TEST_ARRAY = new String[] {"test", "test1"}; Public static final String[] values() { return TEST_ARRAY.clone(); } | cs |
정리하면
멤버 변수는 특별한 경우가 아니면 모두 private로 선언.
정보 은닉을 통해 의존성을 낮추자.
출처 : 조슈아 블로크, 『 Effective Java 2/E』, 이병준 옮김, 인사이트(2014.9.1), 규칙13 인용.
'JAVA > Effective Java' 카테고리의 다른 글
클래스와 인터페이스 - 규칙 15 변경 가능성을 최소화하라 (0) | 2018.05.29 |
---|---|
클래스와 인터페이스 - 규칙 14 public 클래스 안에는 public 필드를 두지 말고 접근자 메서드를 사용하라 (0) | 2018.05.29 |
모든 객체의 공통 메서드 - 규칙 12 Comparable 구현을 고려하라. (0) | 2018.05.29 |
모든 객체의 공통 메서드 - 규칙 11 clone을 재정의할 때는 신중하라 (0) | 2018.05.29 |
모든 객체의 공통 메서드 - 규칙 10 toString은 항상 재정의하라 (0) | 2018.05.29 |