The Iterator Pattern is a behavioral design pattern which provides a way to access the elements of an aggregate object sequentially without exposing its underlying representation. This pattern gives you a way to step through the elements of an aggregate without having to know how things are represented under the covers.
When we allow a aggregate class to do more than one thing like taking more responsibilities like iteration then we have given the class two reasons to change. It can change if the collection changes in some way, and it can change if the way we iterate changes. The design principle “A class should have only one reason to change” will be violated if we mix the iteration logic into the aggregate class.
Lets code the iterator pattern for the AlertAggregator class which is basically an aggregator of alerts. We will have a method called iterator which will return our custom iterator which we will be using to iterate over the alert aggregator.
Lets start with the iterator trait
trait CustomIterator[T] { def hasNext():Boolean; def next():T }
Below is the alert domain object
class Alert(var elementId:Int,var metricMetadataId:Int,var metricMetadataHourlyId:Int,var durationType:String,var durationInterval:Int) { }
Lets code the AlertAggregator which has a method iterator which will return the iterator
class AlertAggregator(val list:ListBuffer[Alert]) { def iterator():AlertIterator= { new AlertIterator(this) } }
Lets code the AlertIterator which has the actual implementation of the iteration
import scala.collection.mutable.ListBuffer class AlertIterator(alertAgg: AlertAggregator) extends CustomIterator[Alert] { var list: ListBuffer[Alert] = alertAgg.list var position: Int = 0; def hasNext(): Boolean = { if (position >= list.size) { return false; } else { return true; } } def next(): Alert= { val alert=list(position) position+=1 alert } }
Driver code
object Test extends App { var list=scala.collection.mutable.ListBuffer[Alert](); var alert1=new Alert(1,2,3,"PW",4); var alert2=new Alert(2,2,3,"PW",4); var alert3=new Alert(3,2,3,"PW",4); var alert4=new Alert(4,2,3,"PW",4); list +=alert1 list +=alert2 list +=alert3 list +=alert4 var agg=new AlertAggregator(list) var iterator=agg.iterator() while(iterator.hasNext()) { println(iterator.next().elementId) } }
I have created an alert iterator code just to show how we can create our own iterators but actually we don’t require this code as ListBuffer already implements the iterator interface and we could have directly returned the same iterator directly.