Design Patterns in Swift: Iterator Pattern

This article will help you understand the iterator pattern it will enable you to build your custom iterators and understand the built-in iterators.Iterator pattern is a perfect choice for you when you need to traverse a collection of objects. It’s fairly simple and it’s so widely used that most collection types implement this pattern in the swift standard library. In this article you’ll learn how to implement the iterator pattern. This will also help you understand how the built-in iterators work and will enable you to build your custom iterators if the system iterators are not sufficient for your needs.

Iterator Pattern

Of all the patterns we covered so far this is one of the simpler ones. As the name suggests, the pattern enables you to iterate over a collection of elements. Here is the definition from the gang of four:

Provide a way to access the elements of an aggregate object sequentially without exposing its underlying representation.

This is all the pattern is doing. It gives you an interface that will enable you to iterate over collections regardless of how they’re implemented in the background. Imagine you had a custom class that holds a collection of vehicles, if your class implemented this pattern then it wouldn’t matter to the other classes how you’re storing these vehicles. You could store them in an array, dictionary, linked list, it’s up to you. We’ll see this in the example later.

Our Example

In the example we’ll use four different classes and store four different collections of vehicles… Array, dictionary, linked list and a wrapper object. We’ll have one class that will print out all the vehicles from these classes. Let’s see it on a diagram:

Our ‘VehiclesInventory’ will use ‘VehicleQueue’, ‘Factory’, ‘ParkingLot’ and ‘Garage’ classes. Each of those classes will store vehicles in a different collection type. From the point of ‘VehiclesInventory’ it won’t matter what the underlying collection is. It won’t be aware of the implementation details.

In order to do this we’ll need four different iterators, one for each collection type that we’ll be using. Let’s go over some code.

VehicleIterator

This is a simple protocol that our custom iterators will implement:

As you can see, the protocol has only one function that will return the next element in the collection, or ‘nil’ if there are no more elements to return.

We’ll implement a custom iterator for each of the collection types that we’ll be using. Our array iterator looks like this:

We initialise this iterator with an array of vehicles and we keep a cursor to the current element in the array. Every call to the ‘next’ function will move the cursor by one. And before you say it, we could have implemented this with generics, but I wanted to keep the example as simple as possible and focus on the pattern itself.

Let’s look at another iterator. The linked list iterator:

Linked list implementation is obviously completely different from the array implementation. We still need to keep a reference to the current element (cursor) but it’s much simpler.

By now you get the idea 🙂 Let me show you one more, slightly different, iterator:

‘ManufacturedVehicleIterator’ is subclassing the ‘ArrayVehicleIterator’ and in the constructor it’s extracting the vehicles out of the object that has a vehicle as one of its properties. We certainly could have implemented this without subclassing the ‘ArrayVehicleIterator’, keep an internal array of ‘ManufacturedVehicles’ and return the vehicle property of each array element when calling the ‘next’ function. This is simply another way of implementing it.

Iterable

Iterable is a very simple protocol that will have only one function for generating iterators:

The classes that contain your business logic will implement this protocol. For the sake of argument, let’s say we have a class named ‘Factory’ that’s responsible for producing vehicles on the assembly line. That class could look like this:

The class has an array of ‘ManufacturedVehicle’ objects, one of the properties of the object is the actual vehicle we’re interested in. We have a custom iterator for the ‘ManufacturedVehicle’ array and we simply instantiate it in the ‘makeIterator’ function. The caller of this function won’t know what iterator it’s using, and it won’t care.

One other fictive implementation might use a dictionary to store the vehicles internally. Let’s call this one ‘Garage’:

Here we see that we’re returning another custom iterator, the dictionary iterator.

Using the Iterators

Using the iterators is actually quite simple. We have a class called ‘VehiclesInventory’ that we use to demonstrate this:

This class has no idea how the vehicles are being stored in each of the respective classes. And it shouldn’t care. Imagine if we exposed our implementation and instead of returning an iterator from the ‘Garage’ class we returned the dictionary… If we ever changed that dictionary to an array we would have two classes to modify instead of one. It’s best to keep yourself exposed as little as possible. We all know how easy it is to introduce bugs when modifying existing code. This way we’re simply making sure that we modify as little code as possible in the future.

Testing It Out

In the code snippet above you can see that we’re using a factory to create our collections. This is the factory we’re using:

From the ‘AppDelegate’ we’re simply calling the ‘printVehiclesInventory’ functions and the output looks like this:

That’s it.

Conclusion

As I mentioned before, this pattern is so common and useful that it’s part of the swift standard library. Check out the ‘Sequence‘ and ‘IteratorProtocol‘ to learn more. So, if you’re using the built-in types you can simply use those iterators. But if you need to build your own, or simply want to know how the built-in iterators work, now you know how 🙂

I hope you found this article to be useful to you and that you’ve learned something new today 🙂

From now on, all the code will be committed to GitLab instead of GitHub, so go ahead and check out the demo project on GitLab. Also, all the snippets in the article will be hosted on GitLab and you can find all of them here.

Have a nice day 🙂
~D;

More resources

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.