Iterator 패턴이란? (설명편)

갈아만든배·2023년 4월 27일
0

디자인 패턴 정리

목록 보기
1/3
post-thumbnail

해당 내용은 "JAVA 언어로 배우는 디자인 패턴 입문 3판"을 읽으면서 내용을 정리한 것입니다.

iterator 패턴은 주로 배열이나 List같은 객체들의 집합의 아이템을 순차적으로 읽어서 처리하고 싶을 때,
주로 사용하는 디자인 패턴의 한 종류이다.

iterator 패턴에서는 패턴의 이름대로 Iterable 인터페이스와 Iterator 인터페이스를 이용하여
객체의 집합체와 해당 집합체에 대해 반복하여 처리를 진행할 반복자를 구현하는데,

이 중 Iterable 인터페이스를 집합체, Iterator 인터페이스를 반복자로 사용한다.


이제, 본격적으로 세부 내용을 살펴보자.

Iterable

먼저 살펴볼 인터페이스는 Iterable 이다.

여기서 Iterable 인터페이스는 이름 그대로 반복이 가능한 객체를 뜻하는데, 흔히 우리가 사용하는 List 객체가 Iterable 인터페이스를 구현한 구현체이다.

정확히는 List의 부모 인터페이스인 Collection 인터페이스가 Iterable 인터페이스를 구현하고 있는데, 이로 인해 List 객체들은 내부에 iterator() 메소드를 포함하고 있다.

Iterator

집합체에 대해 알아봤으니, 이제 해당 집합체의 내부를 순환할 반복자 객체인 Iterator 인터페이스에 대해 알아보자.

앞서 내용에서, Iterable 인터페이스는 집합체라고 설명했는데, 여기서 집합체란 어떤 객체에 대한 모음이라고 생각하면 된다.

예를 들어 보자.

어느 날 우연히 OCN에서 방영하던 해리포터 영화를 보고, 오랜만에 소설판으로 다시 읽어 보고 싶어진 나는 해리포터 전권을 빌리려고 동네 책방에 들렀다.

수 많은 책들 가운데, 나는 해리포터 전 권이 꽂혀 있는 책장 앞에 서서 해리포터 전 권을 모두 꺼내어 카운터로 향했다.

이 때의 상황을 디자인 패턴에 대입해보자.

이 상황에서 '해리포터' 라는 시리즈는 해리포터와 마법사의 돌, 비밀의 방, etc. 등 해리포터라는 이름을 가진 소설책 객체에 대한 집합체라고 볼 수 있다.

해리포터 1권을 Book이라는 객체로 생각했을 때, 해리포터라는 시리즈는 Iterable < Book >이라고도 볼 수 있다.

다른 예시를 보자.

나는 현재 새해 기념으로 독서실을 다녀보려고 결심했다.

집 근처에 저렴한 독서실이 있어 해당 독서실의 자리를 잡은 나는 가져온 책들을 모조리 독서실 책상의 서랍에 꽂아 넣었다.

이 때의 상황을 디자인 패턴에 대입해보자.

이 상황에서 내가 독서실에 가져온 책들을 객체라는 관점에서 봤을 때, 책들이 꽂혀 있는 독서실의 책상 서랍은 내가 가져온 책들에 대한 집합체로 볼 수 있다.


이 관점에서 Iterator 인터페이스를 다시 보자.

Iterator 인터페이스는 next() 메소드와 hasNext() 메소드를 가진 인터페이스이다.

먼저, next() 메소드는 현재 인덱스에 위치한 객체를 반환하는 메소드이다.

이 때 해당 메소드는 객체를 반환하고나서 내부적으로 인덱스를 하나 증가시켜, 다음 순서의 인덱스에 위치시킨다.

이로써 해당 메소드 이후에 인덱스를 증가시키지 않아도, 다음 순서에 객체에 접근할 수 있다.

이쯤에서 의문이 들 수 있다.

내부적으로 인덱스를 늘리는데 대체 어디까지 인덱스를 늘려야 해? 값이 얼마나 더 있는거야?

해당 부분에서 비롯되는 의문을 해소하기 위해 사용하는 것이 hasNext() 메소드이다.

해당 메소드는 이 Iterator 내부에 위치한 인덱스가 가르키는 위치에 값이 존재하는지에 대한 여부를 반환해 준다.

예를 들어보자.


우리는 1 ~ 5까지 수를 가지고 있는 길이가 5인 Iterator 객체가 있다고 가정해보자.

배열 내부에는 작은 순서대로 1부터 5까지의 수가 저장되어 있고, 해당 Iterator 내부 인덱스는 초기 값으로 0을 저장하고 있다.

이 때 hasNext() 메소드를 실행할 경우, 해당 메소드는 현재의 인덱스에 위치한 값이 존재하는지에 대한 여부를 알려주므로 현재 인덱스 위치인 0번째의 위치하는 값이 있는지 확인한 후 여부를 알려준다.

현재 0번째의 위치에는 1이라는 값이 존재하므로 hasNext() 메소드는 true 값을 반환하게 된다.

이후 값이 존재한다는 것을 확인한 사용자가 next() 메소드를 호출하면, 해당 메소드에서는 0번째에 위치하는 값인 1을 반환하고 이후 내부 인덱스를 1만큼 증가시킨다.

이렇게 1에서 2, 2에서 3으로 점차적으로 증가하던 Iterator의 내부 인덱스는 0번째에서 4번째까지 점차적으로 증가해 결국 4번째에 위치한 5라는 값을 반환한 후 5로 1만큼 증가하게 된다.

그리고 사용자는 여느 때 처럼 메소드 명 그대로 다음이 있는지 확인하기 위해 hasNext() 메소드를 실행한다.

지금 Iterator 내부의 인덱스는 Iterator 자체의 길이를 넘어서 5번째 위치에 존재하는지도 모르는 값을 가리키고 있다.

Iterator는 사용자에 요청에 따라 5번째 위치에 값이 존재하는지에 대해 확인하는데,

5번째 위치에는,

Iterator는 잠시 머뭇거리더니 이내 고개를 숙였다.

...아무 것도 없었습니다.

Iterator는 씁쓸한듯 입술을 오물거리다 고개를 돌렸다.

그게 마지막이었다.


다음 시간에 계속...

0개의 댓글