Iterator ํŒจํ„ด

[ Programming > Design Pattern ]

[๋””์ž์ธ ํŒจํ„ด] Iterator ํŒจํ„ด

ย Carrot Yoon
ย 2025-10-03
ย 5

Iterator ํŒจํ„ด

Iterator ํŒจํ„ด์„ ๊ตฌํ˜„ํ•ด์„œ ์„œ๋กœ ๋‹ค๋ฅธ ์ž๋ฃŒ๊ตฌ์กฐ๋ฅผ ๋™์ผํ•œ ๋ฐฉ์‹์œผ๋กœ ์ˆœํšŒํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์•Œ๋ ค๋“œ๋ ค์š”. ์ด ํŒจํ„ด์œผ๋กœ ์ž๋ฃŒ๊ตฌ์กฐ๊ฐ€ ๋‹ฌ๋ผ๋„ ํด๋ผ์ด์–ธํŠธ ์ฝ”๋“œ๋ฅผ ์ˆ˜์ •ํ•˜์ง€ ์•Š๊ณ  ์ผ๊ด€๋œ ๋ฐฉ์‹์œผ๋กœ ๋ฐ์ดํ„ฐ์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ์–ด์š”.

Iterator ํŒจํ„ด์ด ์™œ ํ•„์š”ํ•œ๊ฐ€์š”?

์‹ค๋ฌด์—์„œ ์ด๋Ÿฐ ์ƒํ™ฉ์„ ์ž์ฃผ ๋งˆ์ฃผ์น  ์ˆ˜ ์žˆ์–ด์š”. ๋‘ ๊ฐœ๋ฐœํŒ€์ด ๋น„์Šทํ•œ ๊ธฐ๋Šฅ์„ ๊ฐ๊ฐ ๊ฐœ๋ฐœํ–ˆ๋Š”๋ฐ, ํ•œ ํŒ€์€ ๋ฐฐ์—ด์„ ์‚ฌ์šฉํ•˜๊ณ  ๋‹ค๋ฅธ ํŒ€์€ ์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ๋ฅผ ์‚ฌ์šฉํ–ˆ์–ด์š”. ์ด์ œ ๋‘ ๋ฐ์ดํ„ฐ๋ฅผ ํ•ฉ์ณ์„œ ๋ณด์—ฌ์ค˜์•ผ ํ•˜๋Š”๋ฐ ๋ฌธ์ œ๊ฐ€ ์ƒ๊ฒจ์š”.

AํŒ€ - Array๋กœ ์ž๋ฃŒ ๊ตฌํ˜„

BํŒ€ - ์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ๋กœ ๊ตฌํ˜„

class ArrayInventory {  constructor() {    this.items = [];  }    addItem(item) {    this.items.push(item);  }    getItems() {    return this.items;  }}
class Node {  constructor(data) {    this.data = data;    this.next = null;  }}class LinkedListInventory {  constructor() {    this.head = null;  }    addItem(item) {    const newNode = new Node(item);    if (!this.head) {      this.head = newNode;      return;    }    let current = this.head;    while (current.next) {      current = current.next;    }    current.next = newNode;  }    getHead() {    return this.head;  }}

Client - ๋‘ ํŒ€์˜ Item Collection์„ ํ•ฉ์ณ์„œ ์ถœ๋ ฅ

// ๋‘ ํŒ€์˜ ์•„์ดํ…œ๋“ค์„ ํ•ฉ์ณ์„œ ์ถœ๋ ฅํ•ด์•ผ ํ•จconst arrayInventory = new ArrayInventory();arrayInventory.addItem({ name: '๋…ธํŠธ๋ถ', quantity: 10 });arrayInventory.addItem({ name: '๋งˆ์šฐ์Šค', quantity: 50 });const listInventory = new LinkedListInventory();listInventory.addItem({ name: 'ํ‚ค๋ณด๋“œ', quantity: 30 });listInventory.addItem({ name: '๋ชจ๋‹ˆํ„ฐ', quantity: 15 });// ๋‘ ํŒ€์˜ ์•„์ดํƒฌ ์ถœ๋ ฅ ๋ฐฉ์‹์˜ ์ฐจ์ด๋กœ ๋น„์Šทํ•œ ์ฝ”๋“œ์˜ ๋ฐ˜๋ณตfunction displayAllItems() {  const arrayItems = arrayInventory.getItems();  for (let i = 0; i < arrayItems.length; i++) { // AํŒ€ ์žฌ๊ณ  ์ถœ๋ ฅ    console.log(`${arrayItems[i].name}: ${arrayItems[i].quantity}๊ฐœ`);  }  let current = listInventory.getHead();  while (current) { // BํŒ€ ์žฌ๊ณ  ์ถœ๋ ฅ    console.log(`${current.data.name}: ${current.data.quantity}๊ฐœ`);    current = current.next;  }}

์œ„ Client ์ฝ”๋“œ์˜ ๋ฌธ์ œ์ ์ด ๋ณด์ด์‹œ๋‚˜์š”?

๋ฌธ์ œ์ 

  1. ๋ฐฐ์—ด๊ณผ ์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ๋ฅผ ์ˆœํšŒํ•˜๋Š” ์ฝ”๋“œ๊ฐ€ ์™„์ „ํžˆ ๋‹ฌ๋ผ์š”

  2. ์ƒˆ๋กœ์šด ์ž๋ฃŒ๊ตฌ์กฐ(ํŠธ๋ฆฌ, ์Šคํƒ ๋“ฑ)๊ฐ€ ์ถ”๊ฐ€๋˜๋ฉด ๋˜ ๋‹ค๋ฅธ ์ˆœํšŒ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•ด์•ผ ํ•ด์š”

  3. ํด๋ผ์ด์–ธํŠธ ์ฝ”๋“œ๊ฐ€ ๊ฐ ์ž๋ฃŒ๊ตฌ์กฐ์˜ ๋‚ด๋ถ€ ๊ตฌํ˜„์„ ์•Œ์•„์•ผ ํ•ด์š”

  4. ์ฝ”๋“œ ์ค‘๋ณต์ด ๋งŽ๊ณ  ์œ ์ง€๋ณด์ˆ˜๊ฐ€ ์–ด๋ ค์›Œ์š”

๊ทธ๋Ÿฌ๋ฉด ์œ„์™€ ๊ฐ™์€ ๋ฌธ์ œ์ ์„ ์–ด๋–ป๊ฒŒ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ์„๊นŒ์š”? ๋ฐ”๋กœ Iterator ํŒจํ„ด์„ ์‚ฌ์šฉํ•˜๋ฉด Collection์„ ๊ฐ™์€ ์ธํ„ฐํŽ˜์ด์Šค๋กœ ์ˆœํšŒํ•˜๊ฒŒ ๋งŒ๋“ค์–ด Client๋Š” ๊ฐ ํŒ€์˜ ๋‚ด๋ถ€ ๊ตฌํ˜„์— ๋Œ€ํ•ด์„œ ์•Œ ํ•„์š”๊ฐ€ ์—†์–ด์ ธ์š”. ๊ทธ๋ฆฌ๊ณ  ์ƒˆ๋กœ์šด ๋ฐฉ์‹์˜ Collection์œผ๋กœ CํŒ€์ด ์ถ”๊ฐ€ ๊ตฌํ˜„์„ ํ•ด๋„ Iterator ์ธํ„ฐํŽ˜์ด์Šค ๋ฐฉ์‹์— ๋”ฐ๋ผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ฒŒ๋˜๋ฉด ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ๋‚ด๋ถ€ ๊ตฌํ˜„์„ ์•Œ ํ•„์š”๊ฐ€ ์—†์–ด์ ธ์š”.

Iterator ํŒจํ„ด์œผ๋กœ ํ•ด๊ฒฐํ•˜๊ธฐ

Iterator ํŒจํ„ด์„ ์ ์šฉํ•˜๋ฉด ์ž๋ฃŒ๊ตฌ์กฐ๊ฐ€ ๋‹ฌ๋ผ๋„ ๋™์ผํ•œ ๋ฐฉ์‹์œผ๋กœ ์ˆœํšŒํ•  ์ˆ˜ ์žˆ์–ด์š”.

AํŒ€ ์ดํ„ฐ๋ ˆ์ดํ„ฐ

BํŒ€ ์ดํ„ฐ๋ ˆ์ดํ„ฐ

// ๋ฐฐ์—ด์šฉ Iteratorclass ArrayIterator extends Iterator {  constructor(items) {    super();    this.items = items;    this.index = 0;  }  hasNext() {    return this.index < this.items.length;  }    next() {    return this.items[this.index++];  }}class ArrayInventory {  createIterator() { // ์ดํ„ฐ๋ ˆ์ดํ„ฐ ์ œ๊ณต ๋ฉ”์„œ๋“œ    return new ArrayIterator(this.items);  }}
// ์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ์šฉ Iteratorclass LinkedListIterator extends Iterator {  constructor(head) {    super();    this.current = head;  }  hasNext() {    return this.current !== null;  }  next() {    const data = this.current.data;    this.current = this.current.next;    return data;  }}class LinkedListInventory {  createIterator() { // ์ดํ„ฐ๋ ˆ์ดํ„ฐ ์ œ๊ณต ๋ฉ”์„œ๋“œ    return new LinkedListIterator(this.head);  }}

Client - Iterator ์ ์šฉํ•œ ์ฝ”๋“œ

function displayAllItemsWithIterator() {  const arrayInventory = new ArrayInventory();  arrayInventory.addItem({ name: '๋…ธํŠธ๋ถ', quantity: 10 });  arrayInventory.addItem({ name: '๋งˆ์šฐ์Šค', quantity: 50 });    const listInventory = new LinkedListInventory();  listInventory.addItem({ name: 'ํ‚ค๋ณด๋“œ', quantity: 30 });  listInventory.addItem({ name: '๋ชจ๋‹ˆํ„ฐ', quantity: 15 });    // ๋ฐฐ์—ด์ด๋“  ์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ๋“  ๋™์ผํ•œ ์ฝ”๋“œ๋กœ ์ˆœํšŒ! (๋ฐ˜๋ณต๋˜๋Š” ๋น„์Šทํ•œ ์ฝ”๋“œ๊ฐ€ ์‚ฌ๋ผ์ง)  const inventories = [arrayInventory, listInventory];  inventories.forEach((inventory, idx) => {    console.log(`\n=== ์žฌ๊ณ  ${idx + 1} ===`);    const iterator = inventory.createIterator();        while (iterator.hasNext()) {      const item = iterator.next();      console.log(`${item.name}: ${item.quantity}๊ฐœ`);    }  });}displayAllItemsWithIterator();

์–ด๋•Œ์š”? Client๋Š” Iterator ์ธํ„ฐํŽ˜์ด์Šค๋งŒ ์•Œ์•„์•ผํ•˜๋‹ˆ ๊ฐ ํŒ€์ด ์–ด๋–ค ์ž๋ฃŒํ˜•์„ ์ผ๋Š”์ง€ ์ „ํ˜€ ์•Œ ํ•„์š”๊ฐ€ ์—†์–ด์กŒ์Šต๋‹ˆ๋‹ค.

Iterator ํŒจํ„ด ํด๋ž˜์Šค ๋‹ค์ด์–ด๊ทธ๋žจ

Iterator ํŒจํ„ด์˜ ํด๋ž˜์Šค ๋‹ค์ด์–ด๊ทธ๋žจ์ด ์–ด๋–ป๊ฒŒ ๋˜๋Š”์ง€ ๋ณด์—ฌ๋“œ๋ฆด๊ฒŒ์š”.

Mermaid Chart - Create complex, visual diagrams with text. A smarter way of creating diagrams.-2025-10-03-113056.webp

client๋Š” createInterator() ํ•จ์ˆ˜๋ฅผ ๊ตฌํ˜„ํ•˜๋Š” Aggregate์ด๋ผ๋Š” ๊ณตํ†ต๋œ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ํ†ตํ•ด ๊ฐ์ฒด ์ปฌ๋ ‰์…˜์˜ ๊ตฌํ˜„๊ณผ ๋ถ„๋ฆฌ๋  ์ˆ˜ ์žˆ์–ด์š”. ๊ทธ๋ฆฌ๊ณ  Iterator ์ธํ„ฐํŽ˜์ด์Šค๋งŒ์„ ์‚ฌ์šฉํ•ด Collection์„ ์ˆœํšŒํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

Iterator ํŒจํ„ด vs ์ง์ ‘ ์ ‘๊ทผ ๋น„๊ต

๊ตฌ๋ถ„

Iterator ํŒจํ„ด

์ง์ ‘ ์ ‘๊ทผ

์ฝ”๋“œ ํ†ต์ผ์„ฑ

๋ชจ๋“  ์ž๋ฃŒ๊ตฌ์กฐ๋ฅผ ๋™์ผํ•œ ๋ฐฉ์‹์œผ๋กœ ์ˆœํšŒ

์ž๋ฃŒ๊ตฌ์กฐ๋งˆ๋‹ค ๋‹ค๋ฅธ ์ฝ”๋“œ ํ•„์š”

์œ ์ง€๋ณด์ˆ˜

์ƒˆ ์ž๋ฃŒ๊ตฌ์กฐ ์ถ”๊ฐ€ ์‹œ ๊ธฐ์กด ์ฝ”๋“œ ์ˆ˜์ • ๋ถˆํ•„์š”

๋ชจ๋“  ์‚ฌ์šฉ์ฒ˜๋ฅผ ์ฐพ์•„ ์ˆ˜์ • ํ•„์š”

์บก์Аํ™”

๋‚ด๋ถ€ ๊ตฌ์กฐ ๊ฐ์ถค

๋‚ด๋ถ€ ๊ตฌ์กฐ ๋…ธ์ถœ

ํ™•์žฅ์„ฑ

์ƒˆ Iterator๋งŒ ์ถ”๊ฐ€ํ•˜๋ฉด ๋จ

์กฐ๊ฑด๋ฌธ์ด ๊ณ„์† ๋Š˜์–ด๋‚จ

๋งˆ๋ฌด๋ฆฌ

์ด๋ ‡๊ฒŒ Iterator(๋ฐ˜๋ณต์ž) ํŒจํ„ด์„ ํ†ตํ•ด์„œ ์„œ๋กœ ๋‹ค๋ฅธ ์ž๋ฃŒ๊ตฌ์กฐ์ธ Collection์„ ํ†ต์ผ๋œ ์ธํ„ฐํŽ˜์ด์Šค๋กœ ๋‹ค๋ฃฐ ์ˆ˜ ์žˆ๊ฒŒ ๋งŒ๋“ค์–ด ๋ดค์Šต๋‹ˆ๋‹ค. ์ด๋ ‡๊ฒŒ ํ•จ์œผ๋กœ์จ ๋‚ด๋ถ€ ๊ตฌ์กฐ๋ฅผ ์•Œ ํ•„์š”๊ฐ€ ์—†์–ด์ง€๋‹ˆ ์บก์Аํ™”๊ฐ€ ๋˜๊ณ , ์œ ์ง€๋ณด์ˆ˜ ๊ด€์ ์—์„œ๋„ ์ƒˆ๋กœ์šด ์ž๋ฃŒํ˜•์ด ์ถ”๊ฐ€๋˜๋„ Iterator๋งŒ ์ถ”๊ฐ€ํ•˜๊ณ  Client ์ฝ”๋“œ๋ฅผ ๊ณ ์น˜์ง€ ์•Š์•„๋„ ๋˜๋‹ˆ OCP ์›์น™๋„ ์ž˜ ๋”ฐ๋ฅด๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋ฉด ํ•ญ์ƒ Collection์„ ๋‹ค๋ฃฐ๋•Œ ํŒจํ„ด์„ ์‚ฌ์šฉํ•˜๋ฉด ๋ ๊นŒ์—ฌ?? ์•„๋‹ˆ์š” ๋‹จ์ผ ์ž๋ฃŒ๊ตฌ์กฐ๋งŒ ์‚ฌ์šฉํ•œ๋‹ค๊ฑฐ๋‚˜, ์ˆœํšŒ ๋กœ์ง์ด ํ•œ ๊ณณ๋งŒ ์žˆ๋‹ค๋˜๊ฐ€, ์•„๋‹ˆ๋ฉด ๋‚ด๋ถ€ ๋ฐ˜๋ณต์ž(internal iterator[ex. map, foreach])๋กœ ์ถฉ๋ถ„ํžˆ ์ฒ˜๋ฆฌ ๊ฐ€๋Šฅํ•˜๋ฉด ํ•„์š”์—†์Šต๋‹ˆ๋‹ค. ์•„๋ฌดํŠผ Iterator ํŒจํ„ด์˜ ์ง„์ •ํ•œ ๊ฐ€์น˜๋Š” ์„œ๋กœ ๋‹ค๋ฅธ ์ž๋ฃŒ๊ตฌ์กฐ๋ฅผ ํ†ต์ผ๋œ ์ธํ„ฐํŽ˜์ด์Šค๋กœ ๋‹ค๋ฃฐ ์ˆ˜ ์žˆ๊ฒŒ ๋œ๋‹ค๋Š” ์ ์ด์—์š”. ์ด๋ฅผ ํ†ตํ•ด ์ž๋ฃŒ๊ตฌ์กฐ์˜ ๋ณ€๊ฒฝ์— ์˜ํ–ฅ๋ฐ›์ง€ ์•Š๊ณ , ํ™•์žฅ๋„ ์‰ฌ์›Œ์ง‘๋‹ˆ๋‹ค.