Design Patterns

Iterator Pattern?!

JoonSwift 2022. 2. 4. 13:36

ReactiveX 홈페이지에 들어가보면 바로 확인할 수 있는 이 단어! 

reactivex.io

Iterator pattern? 그게 뭘까 하는 마음에 찾아보았습니다.

Iterator pattern?

Object-Oriented Programming에서 Iterator Pattern은 IteratorContainer(Collection)순회(traverse)할 수 있게 해주고, 그 Container의 요소들에 접근(access)할 수 있게 해주는 디자인 패턴입니다. 

Iterator : Iterator란 프로그래머로 하여금 container(collection)나 특정 list들을 순회(traverse)할 수 있게 해주는 객체입니다.

Container라는 용어는 현재 Collection이라는 단어로 바뀌어야 한다고 Wikipedia에서 토론중이라고 하네요! 저는 Collection이라는 용어가 더 편하니 Collection으로 사용하겠습니다. 

 

Iterator 패턴은 어떤 Collection에 대한 접근과 순회 알고리즘을 Colllection으로 부터 분리(decouple)시켜주어야 합니다. 즉, 

알고리즘이 Iterator 객체의 알고리즘으로 구현되어 있어야 하지, 특정 Collection을 위해서만 구현되어있으면 안된다는 의미입니다. 

이 문단을 제가 이해한 바를 코드로 한번 작성해보았습니다.

protocol MyIterator {
  func searchForElement(at: Int)
}

extension MyIterator {
  func searchForElement(at: Int) {
    print("Search For Element!")
  }
}

struct MyIteratorCollection: MyIterator { }

struct MyCollection {
  func searchForElement(at: Int) {
    // ...
  }
}

위의 코드에서 MyIterator는 현재 어떠한 Collection의 요소에 접근하는 searchForElement(at: ) 라는 메서드를 가지고, 구현을 해두었습니다. 그리고 아래에는 MyIteratorCollection 이라는 Collection과 MyCollection이라는 Collection이 있습니다. 

 

MyIteratorCollection은 현재 MyIterator 프로토콜을 채택하여, 외부에서 searchForElement(at: ) 메서드를 호출할 때 MyIterator에 구현해놓은 메서드를 호출합니다. 이는 MyIteratorCollection 외에도 MyIterator 포로토콜을 채택하는 모든 Collection들이 동일한 searchForElement(at: ) 메서드를 가지고 요소에 접근하게 될 것 입니다. 

 

하지만 아래의 MyCollection의 경우 물론, 해당 Collection의 특별한 이유가 있는 접근 메서드는 필요할 수 있습니다. 하지만 그렇지 않은 경우에는 저렇게 따로 searchForElement(at: ) 메서드를 MyCollection 이 구현하여 가지고 있으면 안된다는 의미로 해석해 보았습니다.

 

Iterator pattern 은 어떤 문제를 해결해 줄까?

  • 객체 Collection의 요소들에 대한 접근과 순회 구현부(representation)를 노출시키고 싶지 않을 때.
  • 객체 Collection을 위한 새로운 순회 operation들을 정의할 때, 인터페이스의 변화가 있어서는 안될 때.

접근과 순회에 대한 operation들을 객체의 인터페이스에 정의하게 되면 코드의 유연성이 떨어지게 됩니다(Inflexible). 왜냐하면 이는 위의 코드에서도 볼 수 있지만, 해당 객체 만을 위한 operation들이며, 나중에 새로운 operation들을 추가하려고 하면 해당 객체의 인터페이스를 건들지 않고는 추가할 수 없습니다.

 

Iterator pattern의 해결 방안?

  • 어떤 객체의 Collection에 대한 접근과 순회할 수 있게 하는 방법을 캡슐화 한 Iterator 객체를 정의합니다.
  • Client들은 구현부를 알 필요 없이 Iterator를 사용하여 해당 Collection에 대한 접근과 순회를 할 수 있게 합니다. (위의 예시 코드에서 MyIterator 프로토콜을 채택하면, searchForElement(at: ) 메서드의 구현부를 몰라도 해당 타입에 대한 접근과 순회를 할 수 있게 제공하는 것과 같다고 생각해볼 수 있을것같습니다.)

Iterator pattern in Swift?

이 Iterator pattern은 이미 Swift를 사용하면서 정말 많은 부분에 사용하고 있습니다. Swift에서는 이미 IteratorProtocol 이라는 프로토콜을 제공하고 있습니다. 이 IteratorProtocol을 채택하는 Iterator Object는 요소들에 for in loop를 통해 접근할 수 있게 됩니다. 

혹은 IteratorProtocol 을 채택하고 있는 Sequence 프로토콜을 채택하는 방법도 있습니다. Sequence 프로토콜은 더 나아가 고차함수인 map, filter 등의 이미 자주 사용하고 있던 고차함수들을 제공하고 있습니다. (나도 모르게 Iterator pattern을 이미 사용(?)하고 있었던 것..)

 

정리

Wikipedia로 Iterator pattern에 대한 정리를 해보았습니다. 열심히 번역을 해보면서 이해해보았지만, 혹시나 잘못 알고 있거나, 번역하면서 실수가 있어 잘못된  용어를 사용한 부분이 있다면 말씀해주시면 감사하겠습니다!

 

참고 문헌

https://en.wikipedia.org/wiki/Iterator_pattern

 

Iterator pattern - Wikipedia

In object-oriented programming, the iterator pattern is a design pattern in which an iterator is used to traverse a container and access the container's elements. The iterator pattern decouples algorithms from containers; in some cases, algorithms are nece

en.wikipedia.org

https://developer.apple.com/documentation/swift/iteratorprotocol

 

Apple Developer Documentation

 

developer.apple.com