티스토리 뷰

반응형

어설프게 설계된 컴포넌트와 잘 설계된 컴포넌트의 가장 큰 차이는 클래스 내부 데이터와 내부 구현 정보를 외부 컴포넌트로부터 얼마나 잘 숨겼느냐다. 잘 설계된 컴포넌트는 모든 내부 구현을 완벽하게 숨겨, 구현과 API 를 깔끔하게 분리한다. 이러한 개념은 OOP 의 원칙 중 하나인 캡슐화, 정보 은닉을 지키기 위한 이다.

 

그러면 이러한 정보 은닉을 구현함으로써 얻을 수 있는 장점들에 대해서 살펴보자.

 

  1. 시스템 개발 속도를 높인다. 여러 컴포넌트를 병렬로 개발할 수 있기 때문이다.
  2. 시스템 관리 비용을 낮춘다. 각 컴포넌트를 빨리 파악해서 디버깅할 수 있고, 다른 컴포넌트로 교체하는 부담도 적기 때문이다.
  3. 정보 은닉 자체가 성능을 높여주지는 않지만, 성능 최적화에 도움을 준다.
  4. 소프트웨어 재사용성을 높인다. 외부에 거의 의존하지 않고 독자적으로 동작할 수 있는 컴포넌트이기 때문이다.
  5. 큰 시스템을 제작하는데 있어 난이도를 낮춰준다. 시스템 전체가 완성되지 않은 상태에서도 개별 컴포넌트의 동작을 검증할 수 있기 때문이다.

사실 내가 느끼기에 1번 4번 5번은 같은 의미인 것 같다. 결국 정보 은닉 그 자체로부터 오는 장점이라기 보다는 인터페이스를 분리해서 개발함으로써 재사용성을 높이고 결합도를 낮추는 것에 의의가 있는 것 같다.

 

자바에서는 캡슐화를 위한 다양한 방법을 제공하지만 이번 포스팅에서는 그 중 접근제어자에 대해서 알아본다.

접근제어자로 캡슐화 구현하기!


핵심은 간단하다! 모든 클래스와 멤버의 접근성을 가능한 한 좁혀야 한다. 약간 최소 권한의 원칙처럼 당연하지만 지키기 어렵고 애매한.. 내용인 것 같다.

 

그럼 자바에서 제공하는 접근제어자에는 어떠한 것들이 있는지 살펴보자.

 

  • private : 해당 클래스 내부에서만 접근할 수 있다.
  • package-private (default) : 동일한 패키지에서만 접근할 수 있다.
  • protected : 이 클래스를 상속받은(구현한) 하위 클래스에서 접근할 수 있다.
  • public : 모든 곳에서 접근할 수 있다.

기억해야 할 것은 아래로 내려올 수록 더 넓은 접근성을 가지고 당연히 아래의 접근제어자는 위의 것들의 접근범위를 포함한다!! (즉, protected 접근제어자는 package-private 의 접근범위를 포함한다)

 

우선 클래스 파일의 제일 밖의 클래스에 부여할 수 있는 접근제어자에 대해서 알아보자. 기본적으로 package-private 과 public 두 가지 접근제어자를 사용할 수 있는데 public 을 부여하게되면 공개 API 가 되는 것이고 package-private 은 패키지 내부에서만 접근할 수 있게 되는 것이다.

 

패키지 외부에서 사용될 일이 없다면 package-private 를 선언하는 것이 좋고 이렇게 함으로써 클래스 수정이 있을 때 클라이언트는 아무런 피해 없이 다음 버전으로 수정, 교체, 제거할 수 있다.
(이후 추가적인 버전개발이 진행 되더라도 하위 호환을 관리하지 않아도 된다)

 


public 클래스의 인스턴스 필드는 되도록 public 이 아니어야 한다.

 

꼭 필요한 구성요소가 상수라면 public sataic final 필드로 공개해도 좋다. 하지만 이러한 필드는 반드시 기본 타입 값이나 불변 객체를 참조해야 한다. 그렇지 않을 경우 final 이 아닌 필드와 다를 것이 없다. 참조되는 객체 자체를 수정할 수는 없겠지만 참조하고 있는 객체 자체가 수정될 수 있기 때문이다.

 

비슷한 맥락으로 길이가 0이 아닌 배열은 모두 변경 가능하니 주의하자.

public static final Thing[] VALUES = { ... };

 

배열 자체에 어떤 객체들이 할당되어 있는지를 수정할 수 없겠지만 객체 자체를 수정할 수 있기 때문이다. 위와 같은 코드를 사용하기 위해서 아래 두 가지 대안이 있다.

private static final Thing[] PRIVATE_VALUES = { ... };
public static final List<Thing> VALUES =
	Collections.unmodifiableList(Arrays.asList(PRIVATE_VALUES));
    
    
private static final Thing[] PRIVATE_VALUES = { ... };
public static final Thing[] values() {
	return PRIVATE_VALUES.clone();
}

 

 

반응형
반응형
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
TAG
more
«   2024/05   »
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 31
글 보관함