[수정중] 헤드퍼스트 디자인 패턴 [9]
헤드퍼스트 디자인 패턴[9]
- 이터레이터 & 컴포지트 패턴
책의 예제로 이해하자. 아침메뉴 식당과 팬케이크 식당이 합쳐졌다!
식당메뉴 표시와 메뉴 구현이 원래 두개였고, 각각의 요리요소를 저장하는 컬렉션도 다르다. 이걸 한번에 하려면?
-> 바뀌는 부분을 캡슐화하라!
-> 객체 컬렉션의 형식이 다르기 때문에 반복작업을 하는 방법이 달라지는 부분이다.
소스로 이해하는게 더 빠를 듯 싶다!
373페이지의 클래스 다이어그램으로부터 이해!
- java.util.Iterator를 사용
- createIterator가 정의된 인터페이스 Menu를 새로 불러옴.
-> 구상 Iterator 클래스를 만들어서 리턴할 책임을 넘김
PancakeHouseMenuIterator는 그냥 ArrayList의 Iterator를 형태에 맞게 오버라이딩하면 그만. 이말이 즉 구상 Iterator 클래스를 만들고 리턴할 책임을 넘긴다는 것.
이것이 바로 이터레이터 패턴!
이터레이터 패턴: 컬렉션 구현 방법을 노출시키지 않으면서도 그 집합체 안에 들어있는 모든 항목에 접근할 수 있게 해주는 방법을 제공.
장점?
- 컬렉션 구현 방법을 노출시키지 않으면서도 그 집합체 안에 들어있는 모든 항목에 접근할 수 있게 해주는 방법을 제공.
- 각 항목에 일일이 접근해주는 기능을 집합체가 아니라 반복자 객체에서 책임지게 된다
단일 역할 원칙! 한 클래스에서는 한가지 역할만 맡도록 해야한다.
--------------------------------------------------------
| 디자인 원칙 - 8 : 클래스를 바꾸는 이유는 한 가지 뿐이어야 한다. |
--------------------------------------------------------
새로운 메뉴를 추가하는 것 또한 쉽다. 새 클래스를 만들고 Menu를 implement 하게한 후 필요한 요소를 추가한다.
하지만 이 방식은 또다른 문제가 있다! OCP(Open Closed Principle)에 위배됨!
-> 메뉴자체에 대한 Iterator를 고려하라!
---
식당의 디저트 메뉴도 같이 구현해달라고 한다. 서브메뉴!
이건 지금의 코드로는 힘들다. 왜냐면 MainMenu로 묶여있기 때문.
따라서 이것을 해결하려면?
- 메뉴, 서브메뉴, 메뉴항목을 모두 포함할 수 있는 트리구조가 필요하다.
- 각 메뉴에 있는 모등 항목에 대해 돌아가면서 작업할 수 있어야한다.
- 더 유연한 방법으로 반복작업을 해주어야 한다.
이 구조는 컴포지트 패턴으로 해결할 수 있다.
컴포지트 패턴: 객체들을 트리 구조로 구성하여 부분과 전체를 나타내는 계층구조로 나타낼 수 있다. 이 패턴을 이용하면 클라이언트에서 개별 객체와 다른 객체들로 구성된 복합 객체(composite)를 똑같은 방법으로 다룰 수 있다.