일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- 다익스트라
- 스프링
- 헥사고날 아키텍처
- 백준
- 비트마스크
- pandas
- series
- equals
- dataframe
- 알고리즘
- BFS
- java
- DP
- 세그먼트 트리
- Redis
- disjoint set
- 이펙티브 자바
- JPA
- 파이썬
- ddd
- dfs
- 문자열
- 데이터 flow
- 자바
- springboot
- spring security
- 포트앤어댑터 아키텍처
- UML
- docker
- 위상정렬
- Today
- Total
코딩못하는사람
아이템 15,16] 클래스와 멤버의 접근 권한을 최소화 본문
[아이템15]클래스와 멤버의 접근 권한을 최소화
어설프게 설계된 컴포넌트와 잘 설계된 컴포넌트의 차이는 클래스 내부 데이터와 내부 구현 정보를 외부 컴포넌트로 부터 얼마나 잘 숨겼는지에 의해 결정된다.
잘 설계된 컴포넌트는 모든 내부구현을 숨기고 구현과 API를 깔끔하게 분리해서 서로의 내부 동작방식을 알 필요가 없게된다. 이것을 정보은닉 및 캡슐화라고 부른다.
정보은닉의 장점
- 시스템 개발 속도 상승 (여러가지 컴포넌트를 병렬적으로 개발 가능)
- 시스템 관리 비용 절감 (디버깅 및 다른 컴포넌트로 교체하는 부담이 적다)
- 성능최적화에 도움
- 소프트웨어 재사용성을 높인다.(외부 의존도가 거의 없고 독자적이라면 낯선 환경에서도 사용가능)
- 큰 시스템 제작 난이도를 낮춰준다. (전체가 완성되지 않아도 개별 컴포넌트의 동작을 검증할 수 있어서)
자바의 접근 제한자
- private: 멤버를 선언한 톱레벨 클래스에서만 접근할 수 있다.
- package-private(default): 멤버가 소속된 패키지 안의 모든 클래스에서 접근 할 수 있다.
- protected: package-private의 접근 범위를 포함하며, 이 멤버를 선언한 클래스의 하위 클래스에서도 접근할 수 있다.
- public: 모든 곳에서 접근 할 수 있다.
접근 제한자를 제대로 활용하여 모든 클래스와 멤버의 접근성을 가능한 한 좁혀야 한다.다시 말해 가장 낮은 접근수준을 부여해야 한다.
클래스 레벨 접근 제한자
톱레벨 클래스(파일명 = 클래스명)와 인터페이스에 부여할 수 있는 접근 수준은 package-private와 public이다.
1.public으로 사용하면 공개 API가 되고 하위 호환을 위해 영원히 관리해야 한다.
2.package-private로 사용하면 해당 패키지에서만 사용 가능하여 다음 릴리즈에 내부로직을 변경해도 괜찮다.
이너 클래스 사용
한 클래스에서만 사용하는 package-private톱레벨 클래스나 인터페이스를 private static으로 중첩시켜보자.
private static으로 중첩시키면 바깥 클래스 하나에서만 접근할 수 있다.
private과 package-private은 해당 클래스의 구현에 해당하므로 공개 API에 영향을 주지 않는다.
public클래스는 그 패키지의 API인 반면 private과 package-private은 내부구현이다.
public 일 필요가 없는 클래스의 접근수준을 package-private로 줄이는 것이 중요하다.
우선 모든 멤버를 private로 만들고 필요할 경우 점차 늘려주도록 하자.
메서드를 재정의 할 경우 리스코프 치환 원칙에 의해 상위 클래스보다 접근수준을 좁힐 수 없다. ( 단 인터페이스를 구현하는 경우는 모두pulbic으로 해야한다)
코드를 테스트 하려는 목적으로 접근 범위를 넓히는 것을 주의하라.
private-> package-private까지는 괜찮지만 그 이상은 API에 문제가 될 수 있다.
public 클래스의 인스턴스 필드는 되도록 public이 아니어야 한다.
인스턴스 필드가 public이라면 불변식을 보장할 수 없다. thread safe하지 않다.
(상수라면 관례대로 public static final로 공개해도 된다)
public static final 배열 필드를 가지지 말자.
배열은 가변클래스이므로 배열 자체에 대한 참조는 변경할 수 없지만 배열의 각 내용은 변경 가능하기 때문이다.
배열 필드를 갖고자 한다면 private로 만들고 public 불변 리스트를 추가하는 방법, private로 만들고 복사본을 반환하는 방법이 있다.(방어적 복사)
[아이템16] public 클래스에서는 public 필드가 아닌 접근자 메서드를 사용하라.
퇴보 클래스
class Point {
public double x;
public double y;
}
클래스의 데이터 필드에 직접 접근하여 수정이 가능한 퇴보한 클래스이다. 이러한 클래스는 캡슐화의 장점을 갖지 못한다. 불변식을 보장할 수 없고,API를 수정하지 않고는 내부 표현식을 바꿀 수 없다.
접근자와 변경자 메서드를 활용해 캡슐화한 클래스
class Point {
private double x;
private double y;
public Point (double x, double y) {
this.x = x;
this.y = y;
}
public double getX() { return x; }
public double getY() { return y; }
public void setX(double x) { this.x = x; }
public void setY(double y) { this.y = y; }
}
public 클래스라면 접근자와 수정자를 만들어주자.
클래스 내부 표현방식을 언제든지 바꿀 수 있는 유연성을 제공하자.
package-private or private 중첩클래스라면 데이터 필드를 노출해도 상관없다(톱레벨 및 같은 패지키에서만 사용되기 때문)
public 클래스는 절대 가변 필드를 노출하지 말자
'자바 메모장 > 이펙티브 자바' 카테고리의 다른 글
아이템43] 람다보다는 메서드 참조를 사용하라 (0) | 2021.08.16 |
---|---|
아이템42] 익명클래스보다는 람다를 사용하라 (0) | 2021.08.16 |
아이템40,41] @Override 애너테이션,마커 인터페이스 (0) | 2021.07.19 |
아이템 29]이왕이면 제네릭 타입으로 만들라 (0) | 2021.07.11 |
[이펙티브 자바]객체 생성과 파괴 (0) | 2021.06.20 |