대표적인 것은 클래스의 멤버변수로 있는 Collection인터페이스이다.
어떤 책인지 기억이 잘 나지는 않지만, 이미 여러군데의 책에서 다룬 내용이기는 하다.

아래에서 다룰 내용은 추상화, 캡슐화에 대한 이야기다.

클래스에서 get을 써서 외부에 어떤 behvior나 자신의 상태를 expose를 할 때 주의를 해야 할 상황이기도 하다.

첫번째 코드

public class SimpleSet{

   private List<Simple> simpleList = new ArrayList<Simple>();
  
   public List<Simple> getSimpleList() {
       return simpleList ;
   }
}


위와 같은 코드의 문제점은 무엇인가? 우리가 쉽게 쓴 패턴이다. 하지만, 클라이언트 코드에서 simpleList의 레퍼런스를 받은 후 수많은 조작이 가능하다.

심지어 이런 코드도 가능하다.
simpleList.clear()

필요하다면 SimpleSet에 clear를 행위로 만들어줘야한다.
직접적인 호출은 수많은 버그들을 만들 가능성이 커진다. 의도하지 않는 곳에서의 조작으로 디버깅도 어렵게 만든다.

두번째 코드

public class SimpleSet{

   private List<Simple> simpleList = new ArrayList<Simple>();
  
   public List<Simple> getSimpleList() {
       return Collections.unmodifiableList(addedInfoList);
   }
}


위와 같은 코드의 문제점은 무엇인가? 리스트를 바꿀 수 없게 collection API는 위와 같은 proxy(decorator) pattern의 인터페이스를 제공한다. 이제는 외부에서 simpleList 를 readonly만 접근이 가능하다.

세번째 코드

public class SimpleSet{

   private List<Simple> simpleList = new ArrayList<Simple>();
  
   public Iterator<simple> iterator(){
       return this.simpleList .iterator();
   }
}

한번더 생각을 해보자. 외부로 제공할 때 iterator패턴으로 위와 같이 제공을 한다면, 어떨까? 내부에 collection의 인터페이스마져 숨길 수가 있다. 항상 리스트만이 내부적인 알고리즘이나 로직을 처리하기 위해서 최선이라고 얘기를 할수는 없다.

SimpleSet의 로직을 처리할 때 List보다 더 나은 자료구조가 생겼을 때 아주 쉽게 갈아탈수가 있다. 위와 같은 코드는 가장 추상화가 잘된 클래스이다.

사실 첫번째 코드가 아니라면, 두번째나 세번째 코드를 권장하고 가능한 세번째 코드를 이야기를 하고 싶다. 두번째 코드도 collection자체가 워낙에 유연해서 쉽게 만들수 있는 인터페이스이기 떄문이다. 물론, 출력자체를 iterator로 하는 거 자체에 많은 이점도 있기때문에 개발자가 심사숙고해서 선택할 expose 인터페이스이다.

하지만, 첫번째 코드를 사용하지 말자!!

참고문서
http://java.sun.com/j2se/1.4.2/docs/api/java/util/Collections.html
Posted by ologist
 TAG , , ,

블로그 이미지
ologist

공지사항

Yesterday191
Today136
Total34,708

달력

 « |  » 2012.02
      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      

최근에 받은 트랙백

글 보관함