[TIL CS]Iterator패턴과 이터레이터프로토콜

조민수·2022년 9월 20일
0

cs

목록 보기
5/5

2022-09-06
비교적 쉬운 디자인패턴 중 하나이 이터레이터 패턴에 대하여 간단하게 정리해놓고 실제로 자바스크립트 내부에서는 해당 iterator가 어떤식으로 순회하는지 알아보자

🚩이터페이터패턴

이터레이터패턴은 디자인패턴들 중 하나로서 컬렉션과 관계없이 각 요소에 접근할 수 있는 패턴을 의미한다
실제 이터레이터패턴의 정의를 내리는 것 보다 중요한 것은 이터레이터패턴에서의
특징정도를 알아두는게 더 중요할 듯 하다

기본적으로 이터레이터 패턴은

1.next()메소드
2. hasNext()메소드
3. reset()메소드
4. first()메소드
5. current()메소드
6. each()메소드

이런 메소드들을 가지고 대체로 구현이 되어있다
이 중 그래두 제일 핵심적인 기능인 메소드로는
next()메소드와
hasNext()메소드로 말할 수 있다

🙋‍♂️우선 es6이전에 모습

따라서 해당 기능들을 가지고 있는 Iterator를 실제로 한 번 구현해본다면

function Custom_Iterator(items){
    this.index=0;
    //items로 들어오는 이터러블한 자료형에 대한 인덱스정보를 갖고잇음
    this.items=items;//현재들어온 이터러블 자료형
}

Custom_Iterator.prototype={
    reset:function(){
        this.index=0;
    },
    first:function(){
        this.reset();
        return this.next();
    },
    next:function(){
        const value = this.items[this.index++];

        if (this.hasNext()) {
          return {
            done: false,
            value,
          };
        }
    
        return { done: true };
    },
    hasNext:function(){
        return this.index<this.items.length;
    },
    current:function(){
        if(this.hasNext()){
            return{
                done:false,
                value:this.items[this.index]
            }
        }
        else{
            return{
                done:true
            }
        }
    },
    each:function(){
        for(let item=this.first();this.hasNext();item=this.next()){
            console.log(item)
        }
    }

}

const arr=[1,2,3,"hi","bye"];
const iterable=new Custom_Iterator(arr);
//만든 배열을 만든 iterator객체에 넣어준다

while(iterable.hasNext()){
    console.log(iterable.next())
}

console.log(iterable.current())
//현재 정보까지의 찍어보기

iterable.reset();
//다시 인덱스 초기화

iterable.each();

이런식으로 구현을 해서 쓸 수 있다

🙋‍♂️그럼 실제 es6에서의 모습

하지만 실제 es6에서부터는 for of를 통하여 iterable객체를 순회할 수 가 있다

우선 Iterable과 Iterator의 뜻부터 정확히 비교해보자면

Iterable: 이터러블은 이터레이터를 리턴하는 '[Symbol.iterator]'()라는 메소드를 가진 값

Iterator: {value,done}객체를 리턴하는 next()라는 메소드를 가진 값


이와같아 Symbol.iterator는 프로토타입에 이미 구현되어있다

따라서

	const arr=[1,2,3,4];
	let iterator=arr[Symbol.iterator]();
	//Symbol.iterator라는 키값에는 메소드가 저장이 되어있어 해당 메소드를 호출해주면
//이터레이터 객체를 반환해주게 된다

	iterator.next();
	iterator.next();
	iterator.next();
	iterator.next();

	//1,2,3,4값이 순서대로 출력이 되는 것을 알 수 있다
	//위에서 우리가 구현한 내용들이 실제로 이미 Array,Map,Set의 prototype.iterateor로 구현이 되어 있는 것이다

근데 여기서 for of문은 우리가 쓰는 Array,Map,Set들의 프로토타입객체의 iterator에 접근하여 next()메소드를 호출해주면서 순회하다 done값이 true이면 종료하게 된다

	const arr=[1,2,3];
	let iterator=arr[Symbol.iterator]();
	iteraotor.next();

	for (const a of iterator){
      console.log(a);
    }

즉,더 이상 어떤 컬렉션이든 인덱스에 의존한 순회를 하지 않고 iterator라는 객체를 통해 자연스럽게 순회가 되게 되는 것 이다.


<정리>

이터레이터패턴의

장점:

- 하나씩 꺼내서 처리하는 과정을 구현과 분리할 수 있다
- 컬렉션 구현방법을 노출시키지않음녀서 그 집합체 안에 있는 항목에 접근할 수 있다

단점:

- 굳이 간단한 구현에서 iterator패턴을 쓰면 지나치게 설계가 복잡해짐

profile
컬러감이 있는 프론트엔드개발자

0개의 댓글