[์ค์ํํธ ๋์์ธํจํด] ๋ฐ๋ณต์ ํจํด(Iterator Pattern)
๋ฐ๋ณต์ ํจํด(Iterator Pattern)
๋ฐ๋ณต์ ํจํด์ ์ปฌ๋ ์ ์ ๋ด๋ถ ๊ตฌํ์ ๋ ธ์ถํ์ง ์์ผ๋ฉด์ ์ปฌ๋ ์ ์ ๋ชจ๋ ์์์ ์ ๊ทผํ ์ ์๋ ๋ฐฉ๋ฒ์ ์ ๊ณตํฉ๋๋ค.
๋ฐ๋ณต์ ํจํด์ ์ปฌ๋ ์ ๊ฐ์ฒด๋ก๋ถํฐ ๋ฐ๋ณต์ ์ผ๋ก ์ปฌ๋ ์ ์์์ ์ ๊ทผํ๋ ์ญํ ์ ๋ถ๋ฆฌํด๋ด๋ ํจํด์ ๋๋ค. ๋ฐ๋ณต์ ํจํด์ ์ฌ์ฉํ๋ฉด ์ปฌ๋ ์ ์ ์์ ์ ์์๋ค์ ๊ด๋ฆฌํ๋ ์ญํ ์๋ง ์ง์คํ ์ ์๊ณ , ์ด๋ค ์์ฒญ์ ์ํด ํน์ ํ ์์๋ฅผ ์ธ๋ถ๋ก ์๋ ค์ฃผ๋ ์ฑ ์์ Iterator์๊ฒ ๋ชจ๋ ๋งก๊ธธ ์ ์๊ฒ ๋์ฃ .
์ ์์์๋ ์ปฌ๋ ์ ์ ๋ด๋ถ ๊ตฌํ์ ์ธ๋ถ๋ก ๋ ธ์ถํ์ง ์๋๋ค๊ณ ํ๋๋ฐ์, ์ด ์๋ฏธ๋ ์ค์ ๋ก ์ฌ์ฉ๋๋ ์ปฌ๋ ์ ์ด ๋ฐฐ์ด์ธ์ง, ๋ฆฌ์คํธ์ธ์ง์ ๊ฐ์ ์ค์ ๊ตฌ์กฐ์๋ ์ ํ ์๊ด์์ด ๊ฐ ์์๋ค์ ์ ๊ทผ์ ๊ฐ๋ฅํ๊ฒ ํ๋ค๋ ๊ฒ์ ์๋ฏธํฉ๋๋ค. ๊ทธ๋ฅ Iterator๋ฅผ ๋ฐ์์ ๋์ ๋๋ฌํ ๋๊น์ง ๋ค์ ์์๋ฅผ Iterator์๊ฒ ๋ค์ ์์๋ฅผ ์์ฒญํ๊ธฐ๋ง ํ๋ฉด ๋๋๊น์.
๊ทธ๋ผ ๋ฐ๋ณต์ ํจํด์ด ์ด๋ป๊ฒ ๊ตฌ์ฑ๋๋์ง ์์๋ด ์๋ค.
๋ฐ๋ณต์ ํจํด ์ดํดํ๊ธฐ
์ ๊ทธ๋ฆผ์ฒ๋ผ ๋ฐ๋ณต์ ํจํด์ ํฌ๊ฒ ์ธ ๊ฐ์ง ์์๋ก ๊ตฌ๋ถ๋ฉ๋๋ค.
๋จผ์ Iterable ํ๋กํ ์ฝ๊ณผ ์ด๋ฅผ ์ฑํํ๋ ๊ฐ์ฒด์ ๋๋ค. Iterable์ ๋ง ๊ทธ๋๋ก ์ํ๊ฐ ๊ฐ๋ฅํ ์์๋ค์ ๊ฐ์ง๊ณ ์๋ ๊ฐ์ฒด๊ฐ ๋ฉ๋๋ค. ๋ฐ๋ผ์ ์ฐ๋ฆฌ๊ฐ ์ปฌ๋ ์ ์ด๋ผ๊ณ ๋ถ๋ฅด๋, ์ฌ๋ฌ ๊ฐ์ ์์๋ค์ ๊ฐ์ง๊ณ ์๋ ๊ฐ์ฒด๊ฐ Iterable์ด ๋๊ฒ ์ฃ . Iterable์ ์ปฌ๋ ์ ์ ๊ด๋ฆฌํ๋ ์ฑ ์์ ๊ฐ์ง๊ฒ ๋๋๋ฐ์, ๋ฐ๋ณต์ ํจํด์ ์ํด์ ์ด ๊ฐ์ฒด๊ฐ ํ๋ ์ผ์ ๋จ ํ ๊ฐ์ง์ ๋๋ค. ํด๋ผ์ด์ธํธ๊ฐ Iterable ๊ฐ์ฒด ์์ ์๋ ์์์ ์์ฐจ์ ์ผ๋ก ์ ๊ทผํ๊ณ ์ถ์ ๋, ์์์ ์ ๊ทผํ๋ ์ฑ ์์ ๊ฐ์ง๋ ๊ฐ์ฒด๋ Iterator๋ฅผ ์์ฑํด ๋ฐํํด์ฃผ๋ ๊ฒ์ ๋๋ค.
์ด ์์ฒญ์ ์ฒ๋ฆฌํ๋ ๋ฉ์๋๊ฐ createIterator๊ฐ ๋๊ฒ ์ฃ .
์ด์ ๋ฐ๋ณต์ ํจํด์ ํต์ฌ์ด ๋๋ Iterator๋ฅผ ํ์ธํด๋ด ์๋ค. Iterator๋ ๊ธฐ๋ณธ์ ์ผ๋ก ๋ ๊ฐ์ง ๋ฉ์๋๋ฅผ ์ธํฐํ์ด์ค๋ก ์ ๊ณตํด์. ๋ฌผ๋ก ๊ตฌํ์ ๋ฐ๋ผ์ ๋ค๋ฅธ ํธ๋ฆฌํ API๋ฅผ ์ ๊ณตํ ์๋ ์๊ฒ ์ฃ . hasNext๋ ์์ง ํ์ํ์ง ์์ ์์๊ฐ ์กด์ฌํ๋์ง ํ์ธํ๋ ๋ฉ์๋์ด๊ณ , next๋ ๋ค์ ๋ฉ์๋๋ฅผ ๊ฐ์ ธ์ค๋ ๋ฉ์๋์์. ์ด iterator๋ ์ปฌ๋ ์ ์์ ๊ฐ๊ฐ ๊ตฌํํ๊ธฐ ๋๋ฌธ์ ์ธ๋ถ์์๋ ์ปฌ๋ ์ ์ ๋ด๋ถ ๊ตฌํ์ ์์ง ๋ชปํ ์ฑ๋ก hasNext์ next ์ธํฐํ์ด์ค๋ฅผ ํตํด ์์๋ค์ ์ฝ๊ฒ ๋ฉ๋๋ค.
Iterator Pattern ๋ง๋ค์ด๋ณด๊ธฐ
protocol Iterable {
associatedtype Iterator
func makeIterator() -> Iterator
}
protocol Iterator {
associatedtype Element
func hasNext() -> Bool
func next() -> Element?
}
์ดํฐ๋ ์ดํฐ ํจํด์ ์ํด์ ๊ฐ์ฅ ๋จผ์ Iterable๊ณผ Iterator ํ๋กํ ์ฝ์ ์ ์ํ์ต๋๋ค. ์ฐ๋ฆฌ๊ฐ ๊ทธ๋ฆผ์์ ๋ดค๋ ๊ทธ ์ธํฐํ์ด์ค๋ฅผ ๊ทธ๋๋ก ์ ๊ณตํ๊ณ ์์ด์.
final class defaultIterator<T>: Iterator {
typealias Element = T
private var items: [Element] = []
private var current = 0
init(items: [Element]) {
self.items = items
}
func next() -> Element? {
guard hasNext() else { return nil }
defer { self.current += 1 }
return items[current]
}
func hasNext() -> Bool {
current < items.count
}
}
๊ทธ๋ฆฌ๊ณ Iterator์ ๊ตฌ์ฒด ํ์ ์ ์ ์ํ๋๋ฐ์, ๋จผ์ ์ด๊ธฐํ ์์ ์ ์ด๋ค ๋ฐฐ์ด์ ์ ๋ ฅ๋ฐ๊ณ , ํ์ฌ ํ์ ์ค์ธ ์์๋ฅผ ํ์ํ๋ ์ปค์ ์ญํ ์ ํ๋ ๋ณ์์ธ current๋ฅผ ์ ์ํ์ต๋๋ค. hasNext๋ ์ด ์ปค์๋ฅผ ๊ธฐ์ค์ผ๋ก ๋ค์ ๋ฐ์ดํฐ๊ฐ ์๋์ง ํ๋จํ๊ณ , next์์๋ current๋ฅผ ํตํด ๋ฐ์ดํฐ๋ฅผ ๋ฝ์๋ด ๋ฐํ์ ํ๊ฒ ๋ฉ๋๋ค. defer๋ฅผ ์จ๋ณด๊ณ ์ถ์ด์ ํ ๋ฒ ์จ๋ดค์ด์ใ ใ
๊ทธ๋ผ ์ด ํจํด์ ์ด๋ป๊ฒ ์์ฉํ๋ฉด ์ข์์ง ํด๋ผ์ด์ธํธ ์ฝ๋๋ฅผ ๋ง๋ค์ด๋ณผ๊ฒ์.
์ดํฐ๋ ์ดํฐ ํจํด์ ์ ์๋ ์ฑ ์ ์์ ์์ ๊ฐ์ฅ ์๋ฟ์๋ ์ ์ด ๋ด๋ถ ๊ตฌํ์ ์์ง ๋ชปํด๋ ๋ฐ๋ณต์ ๋๋ฆด ์ ์๋ค๋ ๊ฒ์ด์๋๋ฐ์, ๊ทธ๋์ list์ map ๋ ์ข ๋ฅ์ ์ปฌ๋ ์ ์ ๋ํ ํด๋์ค๋ฅผ ๋ง๋ค๊ณ ์ดํฐ๋ ์ดํฐ ํจํด์ ์ ์ฉํด๋ณด์์ต๋๋ค.
final class MapCollection: Iterable {
private var map: [String: String] = [:]
func add(element: String, for key: String) {
map.updateValue(element, forKey: key)
}
func makeIterator() -> defaultIterator<String> {
return defaultIterator<String>(items: self.map.values.map({ $0 }))
}
}
final class ListCollection: Iterable {
private var list: [String] = []
func add(element: String) {
list.append(element)
}
func makeIterator() -> defaultIterator<String> {
return defaultIterator<String>(items: self.list)
}
}
๋ ํด๋์ค ๋ชจ๋ Iterable ํ๋กํ ์ฝ์ ์ ์ํ์ง๋ง ๊ฐ์ ํ์ ์ Iterator๋ฅผ ์์ฑํด์ ๋ฐํํด์ฃผ๊ณ ์์ต๋๋ค. ์ด์ ์ด ํด๋์ค๋ฅผ ์ฌ์ฉํ๋ ์ฌ์ฉ์์ ์ ์ฅ์์๋ ListCollection์ด๋ MapCollection์ด ์ด๋ฆ์ ํตํด ๋ด๋ถ์ ์ผ๋ก ์ด๋ป๊ฒ ๊ตฌํ๋์๋์ง ์ ์ ์์์ง๋ ๋ชฐ๋ผ๋, ๋ฐ๋ณต๋ฌธ์ ๋ง๋ค๊ธฐ ์ํด ๋ด๋ถ ๊ตฌํ์ ์ ํ์๊ฐ ์์ต๋๋ค. ๊ทธ๋ฅ makeIterator()๋ฅผ ๋ถ๋ฌ์ Iterator๋ฅผ ์ป๊ณ , ์์๋ฅผ ํ์ํ๊ธฐ๋ง ํ๋ฉด ๋๊ธฐ ๋๋ฌธ์ด์ฃ .
let map = MapCollection()
let list = ListCollection()
map.add(element: "1", for: "1")
map.add(element: "2", for: "2")
map.add(element: "3", for: "3")
list.add(element: "11")
list.add(element: "22")
list.add(element: "33")
let iterators = [map.makeIterator(), list.makeIterator()]
for iterator in iterators {
while iterator.hasNext() {
print(iterator.next() ?? "0")
}
}
// 3
// 2
// 1
// 11
// 22
// 33
์ด๋ ๊ฒ ๊ฐ๊ฐ์ ํ์ ์ ๋ํ ๋ฐ๋ณต๋ฌธ์ ๋ง๋ค์ง ์์๋, iterator๋ฅผ ํตํด ๋ชจ๋ ์์์ ๋ํ ํ์์ด ๊ฐ๋จํ๊ฒ ๊ฐ๋ฅํด์ง๋๋ค.
๋ง๋ฌด๋ฆฌ
Iterator Pattern์ ํต์ฌ์ ๋ด๋ถ ๊ตฌํ์ ๊ฐ์ถ๋ฉด์๋ ์ฌ์ฉ์๊ฐ ์ปฌ๋ ์ ๊ฐ์ฒด๊ฐ ๊ฐ์ง๊ณ ์๋ ๋ชจ๋ ์์๋ค์ ์ ๊ทผํ ์ ์๋ ๋ฐฉ๋ฒ์ ์ ๊ณตํ๋ค๋ ๊ฒ์ ๋๋ค. ๊ทธ๋ฆฌ๊ณ ๋์์ ์์๋ฅผ ํ์ํ๋ ์ญํ ์ ์ปฌ๋ ์ ๊ฐ์ฒด์์ ๋ถ๋ฆฌํด๋ผ ์ ์์ฃ .
์ฌ์ค ์ค์ํํธ์์๋ IteratorProtocol ์ด๋ผ๋ Foundation ํ๋กํ ์ฝ์ด ์กด์ฌํฉ๋๋ค.
์ด ์์์ฒ๋ผ ์ค์ํํธ๋ Sequence ์ ๋ํด์ Iterator๋ฅผ ์ ๊ณตํ๋๋ฐ์, for animal in animals์ ๊ฐ์ ๋ฌธ๋ฒ์ด ๊ฐ๋ฅํ ์ด์ ๋
๋ด๋ถ์ ์ผ๋ก๋ ์ด๋ ๊ฒ Iterator ํจํด์ ํตํด ๊ตฌํ์ด ๋์ด์๊ธฐ ๋๋ฌธ์ ๋๋ค.
Sequence ํ๋กํ ์ฝ์ ์ฑํํ๋ฉด makeIterator ๋ฉ์๋๋ฅผ ํตํด iterator๋ฅผ ์ป์ ์ ์๋๋ก ๊ตฌํํ ์ ์๊ณ , IteratorProtocol์ ์ฑํํด next() ๋ฉ์๋๋ฅผ ๊ตฌํํ๋ฉด ๋ค์ ์์๋ฅผ ์ป์ ์ ์๋ ๊ตฌํ์ ์ ๊ณตํ ์ ์์ฃ .
์ด๋ ๊ฒ ํด์ Iterator ํจํด์ ๊ณต๋ถํด๋ณด์์ต๋๋ค. Swift์์๋ ๊ธฐ๋ณธ์ ์ผ๋ก ๋ชจ๋ ์ปฌ๋ ์ ์ Iterator๊ฐ ์ ๊ณต๋๊ธฐ ๋๋ฌธ์ ์ง์ ๊ตฌํํ ์ผ์ ๋ง์ง ์๊ฒ ์ง๋ง, ์ Iterator ํจํด์ด ํ์ํ์ง, ์ด๋ค ์ ์์ ์ ์ฉํ ์ง ์กฐ๊ธ์ ์๊ฒ ๋ ๊ฒ ๊ฐ์์.
์ค๋๋ ์ฝ์ด์ฃผ์ ์ ๊ฐ์ฌํฉ๋๋ค!
'๐ฎ ์จ-์์ค > ๐ ๋์์ธํจํด' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
๋๊ธ
์ด ๊ธ ๊ณต์ ํ๊ธฐ
-
๊ตฌ๋
ํ๊ธฐ
๊ตฌ๋ ํ๊ธฐ
-
์นด์นด์คํก
์นด์นด์คํก
-
๋ผ์ธ
๋ผ์ธ
-
ํธ์ํฐ
ํธ์ํฐ
-
Facebook
Facebook
-
์นด์นด์ค์คํ ๋ฆฌ
์นด์นด์ค์คํ ๋ฆฌ
-
๋ฐด๋
๋ฐด๋
-
๋ค์ด๋ฒ ๋ธ๋ก๊ทธ
๋ค์ด๋ฒ ๋ธ๋ก๊ทธ
-
Pocket
Pocket
-
Evernote
Evernote