Ayende @ Rahien

Hi!
My name is Oren Eini
Founder of Hibernating Rhinos LTD and RavenDB.
You can reach me by phone or email:

ayende@ayende.com

+972 52-548-6969

, @ Q c

Posts: 10 | Comments: 37

filter by tags archive

Design patterns in the test of timeIterator

time to read 1 min | 108 words

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 necessarily container-specific and thus cannot be decoupled.

More about this pattern.

It is really hard to think about any other pattern that has been more successful. In particular, patterns have long been about overcoming shortcoming of the language or platform.

In this case, iterators has became part of both language and platform in most modern systems.

  • System.Collection.IEnumerable
  • java.util.Iterator
  • Python’s __iter__()

Basically, it is so good, it is everywhere.

More posts in "Design patterns in the test of time" series:

  1. (21 Jan 2013) Mediator
  2. (18 Jan 2013) Iterator
  3. (17 Jan 2013) Interpreter
  4. (21 Nov 2012) Command, Redux
  5. (19 Nov 2012) Command
  6. (16 Nov 2012) Chain of responsibility
  7. (15 Nov 2012) Proxy
  8. (14 Nov 2012) Flyweight
  9. (09 Nov 2012) Façade
  10. (07 Nov 2012) Decorator
  11. (05 Nov 2012) Composite
  12. (02 Nov 2012) Bridge
  13. (01 Nov 2012) Adapter
  14. (31 Oct 2012) Singleton
  15. (29 Oct 2012) Prototype
  16. (26 Oct 2012) Factory Method
  17. (25 Oct 2012) Builder
  18. (24 Oct 2012) A modern alternative to Abstract Factory–filtered dependencies
  19. (23 Oct 2012) Abstract Factory

Comments

Ryan Heath

Ah, remembering those days when I first met them, C++ STL anyone? ;)

// Ryan

Sergey Shumov

Ayende, what do you think about to write a couple of posts on how things are organized in Hibernating Rhinos? It would be interesting to read about your CI process, development workflow, internal rules, priorities management, etc...

kindof

Ayende, did you know that Scott Hanselman and Rob Conery make jokes of your voice at the end of Hanselminutes 353? :D

Ayende Rahien

Sergey, Sure, do you have any specific questions?

Frisian

The Iterator pattern may be omnipresent, but IMHO that doesn't say anything about its current value: - The abstraction level of the pattern is too low: In order to work, the pattern forces you to place a loop into your code. It's a code smell in my book, if someone else's code dictates the control structures in my code. Iterating over a collection can be abstracted away in a forEach() method, that takes a callback handler, which in turn is invoked for every element of the collection. Every SAX parser works like this. - Because of the low abstraction level the Iterator pattern effectively prohibits parallel execution of a piece of code. Nowadays, that is almost bad in itself. With a dedicated forEach() method on the other hand, that's rather simple: Mark the callback handler as side-effect-free by flag, annotation or marker interface and the iteration can be parallelized. By comparison, every SQL statement is written in a way that allows the database to execute it in parallel. - An iterator is stateful and mutable. Passing around an iterator as an argument leads to complex coupling of the affected code. Refactoring such code will be arduous at best.

Ayende Rahien

Frisian, Where on earth did you get the idea that iterator forbid parallel execution. See Parallel.For and Parallel.ForEach as good counter examples. Sure, iterator is low level, but most design patterns are.

Frisian

I am not a C# programmer, but what I could take from an example for Parallel.ForEach (http://msdn.microsoft.com/en-us/library/dd460720.aspx) seems to prove my point: it's a method with a callback, that is presented one element at a time. And that is definitely not the GoF-Iterator, for which you provided the Wikipedia link in your article. Interestingly, both "standard" implementations (IEnumerator in C#, Iterator in Java) share a common problem: they are mixing command and query. Iterator.next() not only returns the current element, but also advances to the next one. IEnumerator.MoveNext() moves to the next element and tells, if there is a next element at all. Likewise, they both don't adhere to "Tell, don't ask", thus promoting coupling. Lastly, I wasn't complaining about the abstraction level being "low", but being "too low". The loop really doesn't belong on the caller's side.

Ayende Rahien

Frisian, Next / MoveNext does NOT do two things. It tries to move to the next one, returning true if it succeeded. The return value is if the next operation was successful, not if the future next operation will be. And Parallel.ForEach works using an iterator.

Comment preview

Comments have been closed on this topic.

FUTURE POSTS

  1. Production postmortem: The case of the memory eater and high load - one day from now
  2. Production postmortem: The case of the lying configuration file - about one day from now
  3. Production postmortem: The industry at large - 3 days from now
  4. The insidious cost of allocations - 4 days from now
  5. Find the bug: The concurrent memory buster - 5 days from now

And 4 more posts are pending...

There are posts all the way to Sep 10, 2015

RECENT SERIES

  1. Find the bug (5):
    20 Apr 2011 - Why do I get a Null Reference Exception?
  2. Production postmortem (10):
    14 Aug 2015 - The case of the man in the middle
  3. What is new in RavenDB 3.5 (7):
    12 Aug 2015 - Monitoring support
  4. Career planning (6):
    24 Jul 2015 - The immortal choices aren't
View all series

Syndication

Main feed Feed Stats
Comments feed   Comments Feed Stats