Welcome back to series about design pattern in JavaScript. This is a link to follow my articles about design pattern in JavaScript topic. Design pattern series.
Table of
contents:
- What is Iterator design pattern?
- How to implements Iterator design pattern?
- Pratical application
Let’s go to
the content!
What is
Iterator design pattern?
Iterator
pattern is a behavioral design pattern that lets you traverse elements of a
collection without exposing its underlying representation (list, stack, tree,
etc, …).
Iterator
pattern allows to effectively loop over some collection of objects.
How to
implements Iterator design pattern?
We create a
Iterator interface which narrates navigation method and a Aggregaate interface
which returns the iterator concreate a classes implementing the Aggregate
interface will be responsible to implement Iterator interface and use it.
And this is UML class diagram.
Pratical
application
We've just
gone through theories. We go into practice. We will build an Iterator according
to the property, if there are elements, we continue to traverse. We can browse
forward and backward at the same time.
Unlike the
theory we will create an Iterator function that takes the object to be
traversed.
function Iterator(items) {
this.items = items
this.index = 0
}
This.items
is the object we get for browsing. this.index is our pointer, wherever the
pointer goes, the element at that position will be traversed.
Next, we
define methods to iterate over the elements.
Iterator.prototype = {
hasNext: function () {
return this.index < this.items.length
},
next: function () {
return this.items[this.index++]
},
}
We have two
methods, hasNext(), to check whether there are elements in the object being
traversed. And next() is used to browse the next element.
const arr = [1, NaN, 'alo', function () { }, null, true, false, undefined, { name: 'alaba' }, [1, 0], 'String']
const arrIter = new Iterator(arr)
We have an
array consisting of many elements of different types such as number, NaN,
string, function, object, null, boolean, undefined, array. We create a variable
to store the value of the Iterator object.
We'll go
through the elements and print them out to see if our function is working.
while (arrIter.hasNext()) {
console.log(arrIter.next())
}
// => 1, NaN, alo, function arr(), null,
true, false, undefined, Object {name: "alaba"}, Array[1, 0], String
Awesome! So,
we have implemented an Iterator design pattern used to traverse the elements in
the object that needs to be traversed.
Now let's
upgrade the problem a little bit. We will add two methods, hasPrevious() and
previous(), to iterate the elements in the opposite direction.
hasPrevious: function () {
return this.index > 0
},
previous: function () {
return this.items[--this.index]
}
We will
reuse the original object to cycle through the elements. And use serialization
methods.
const arr = [1, NaN, 'alo', function () { }, null, true, false, undefined, { name: 'alaba' }, [1, 0], 'String']
const arrIter = new Iterator(arr)
console.log(arrIter.next()) // => 1
console.log(arrIter.next()) // => NaN
console.log(arrIter.previous()) // => NaN
console.log(arrIter.previous()) // => 1
Great! We
can traverse elements in the forward and reverse direction.
Let's go
through the analysis of Iterator design pattern.
Pros:
Single
Responsibility Principle. You can clean up the client code and the collections
by extracting bulking traversal.
Open/Closed
Priciple. You can implement new type of collections and iterators and pass them
to existing code without breaking anything.
You can
iterate over the same collection in parallel because each iterator object
contains its own iteration state.
For the same
reason, you can delay an iteration and continue it when needed.
Cons
Applying the
pattern can be an overkill if your app only works with simple collections.
Using an
iterator may be less efficient then going through element of some specialized
collections directly.
Conclusion
We just went
through the Iterator design pattern in JavaScript. The Iterator pattern is like
any other design pattern. It is applicable to large problems that need to
traverse difficult and complex objects with algorithms such as DFS, BFS, etc.
You might consider applying the Iterator design pattern to large problems.
If you have
any ideas feel free to comment below. Thank you for joining with me. Having a
good day!
0 Nhận xét