The Iterator Pattern

The iterator pattern is a design pattern which can be used to decouple algorithms from containers.

Let's take a look into what it actually is, how to apply it, and which problems it solves!

🧵👇
1⃣ What problems does it solve?

✅ The elements of an aggregate object should be accessed and traversed without exposing its representation (underlying data structure)

✅ New traversal operations should be defined for an aggregate object without changing its interface
Those two points may sound a little complicated, but you can view it this way:

If you define access and traversal operations within an object's interface (its methods viewable and usable from the outside), it becomes inflexible.
You simply can't change the interface without breaking some code, especially code which implements the interface!

This applies to all code. The one you've written, and the one others have written, third-parties so to say.
But if you provide a common interface, which all containers and users can agree on, you can decouple access and traversal logic completely, and let your container only return one common interface!

🧵👇
2⃣ An example problem

Imagine a collection of friends.

The class Friends abstracts away the underlying storage of friends and uses an array for that.

getFriends(index) already exposes some implementation details, and thus basically ties the container... class Friends {   construct...
...to a certain data structure (an array in this case).

Because what happens if someone wants to loop over all friends?

The implementation could look something like the following. const friends = new Friends...
But what happens if you want to refactor Friends to use a Set?

A Set is an unordered collection. It usually doesn't provide index-based access, and it doesn't necessarily maintain the order of insertion, as the backing implementation may vary!

There you have a problem!

👇
3⃣ Solving the issue

By using an iterator, you can decouple the access and traversal logic of a container from its underlying data structure. class Friends {   construct...
See that interesting looking new method?

That's a JavaScript-specific, a Symbol (a well-known one) which the runtime will call on certain occasions.

One such an occasion is the use of the for..of loop.

You can change the underlying data structure, ... const friends = new Friends...
... you can then change the implementation of the iterator, but every user can still loop over all the elements in the same way!

Most languages provide something like an iterator, be it an object behind a Symbol, an interface, or something similar.

👇
4⃣ Bonus: Some more interesting use cases of iterators in JavaScript

1. Traversing an array in reverse order without reversing the array itself, and thus not modifying it

It may sound tempting to simply reverse an array, but this is an in-place operation... function reversed(array) { ...
...and it can be a costly one if your array is pretty large.

With an iterator, you don't have those issues, because the iterator object itself handles everything, as it only keeps track of the index to return the next element from.

The original array can stay as it is!
2. Creating a range to iterate over, on-demand

No need to create an array and fill it with values, which all need memory, if you can simply generate those numbers on demand! function range(start, endEx...

• • •

Missing some Tweet in this thread? You can try to force a refresh
 

Keep Current with Oliver Jumpertz

Oliver Jumpertz Profile picture

Stay in touch and get notified when new unrolls are available from this author!

Read all threads

This Thread may be Removed Anytime!

PDF

Twitter may remove this content at anytime! Save it as PDF for later use!

Try unrolling a thread yourself!

how to unroll video
  1. Follow @ThreadReaderApp to mention us!

  2. From a Twitter thread mention us with a keyword "unroll"
@threadreaderapp unroll

Practice here first or read more on our help page!

More from @oliverjumpertz

25 Nov
The Proxy pattern

The proxy pattern is a software design pattern.

It is basically, in its simplest form, an interface to something else.

But let's take a look at what it is and how you could use it!

🧵👇🏻
1⃣ What is it?

A Proxy is a wrapper (object), that wraps another object.

Imagine it like a container that looks exactly like the object it wraps, behaves nearly the same, but may add some additional functionality.

You can imagine it, visually, like shown below. Image
If you need another example:

Imagine a wetsuit. It's a thin layer above your body, keeps the shape of your body, but adds the ability to keep you dry inside!

👇🏻
Read 10 tweets
22 Nov
Although I am not a data scientist by any means, I was recently asked what knowledge of math someone would need to be able to efficiently get into the field.

Well, I researched a little and came up with the following course track, starting with the basics.

🧵👇
Calculus 1 will cover a lot of the basics, relevant especially to optimization problems which are quite common in data science.

khanacademy.org/math/calculus-1
Calculus 2 will go even deeper and cover topics such as integration techniques and differential equations.

Especially integrals are pretty important for probability distributions and hypothesis testing!

khanacademy.org/math/calculus-2
Read 7 tweets
21 Nov
DIP - The Dependency Inversion Principle

The Dependency Inversion Principle is a part of SOLID, a mnemonic acronym which bundles a total of 5 design principles.

It is often associated with clean code.

But what exactly is it, is it important to you, should you even care?

🧵👇
1⃣ What does it state?

It states:

Modules that encapsulate high-level policy should not depend upon modules that implement details. Rather, both kinds of modules should depend upon abstractions.

This may sound a little complicated, but you can break it up, as follows:
1. High-level modules should not depend on low-level modules. Both should depend on abstractions (e.g., interfaces).

2. Abstractions should not depend on details. Details (concrete implementations) should depend on abstractions.
Read 17 tweets
20 Nov
ISP - The Interface Segregation Principle

The Interface Segregation Principle is part of SOLID, a mnemonic acronym which bundles a total of 5 design principles.

It is often associated with clean code.

But what exactly is it, is it important to you, should you even care?

🧵👇
1⃣ What does it state?

The ISP sets a pretty simple statement:

"No client should be forced to depend on methods it does not use."

ISP applied to the extreme will result in single method interfaces, also called role interfaces.
You can take a look at the following example to get an idea of how the ISP can be violated in one way (this time it's in TypeScript): interface ReportService {  ...
Read 14 tweets
14 Nov
Clean code is important, clean code helps others understand your code, but clean code is also pretty subjective!

I want to give you my perspective on it, drawing from years of experience leading teams of developers as a tech lead and working in teams.

🧵
1️⃣ Clean code is important

Clean code helps people understand code.

The more your code is structured according to the opinion of the majority of developers, the more likely it is that other developers will understand your code!
A few principles of clean code are:

- Use meaningful and understandable identifiers
- Use functions and keep them as short as possible
- You don’t need comments most of the time when your code is human readable
- Don’t repeat yourself (DRY)
- Keep it Simple, Stupid! (KISS)
Read 18 tweets
27 Oct
Have you ever had to process events?

If you have, have you ever thought about if the order of events really matters?

There is a huge difference in complexity whether the order of events processed matters or not.
Imagine the following task/problem:

You want to analyze application logs, because you're curious how an API that starts a long running background process behaves performance-wise.

One log message signals the start, a few intermediate ones, and one message that signals the end.
1⃣
If you can somehow ensure that every log message you process comes in order, the problem is manageable.

When you get your end message, you know that you already processed the start message.

You could now, for example, just subtract the end time from the start time.
Read 8 tweets

Did Thread Reader help you today?

Support us! We are indie developers!


This site is made by just two indie developers on a laptop doing marketing, support and development! Read more about the story.

Become a Premium Member ($3/month or $30/year) and get exclusive features!

Become Premium

Too expensive? Make a small donation by buying us coffee ($5) or help with server cost ($10)

Donate via Paypal Become our Patreon

Thank you for your support!

Follow Us on Twitter!