//+------------------------------------------------------------------+ //| 201021_113117.mq5 | //| 2019-2020, dimitri pecheritsa | //| 792112@gmail.com | //+------------------------------------------------------------------+ // from: design patterns: elements of reusable object-oriented software // by: gof: erich gamma, richard helm, ralph johnson, john vlissides // published in 1994 //+------------------------------------------------------------------+ //| iterator - behavioral design pattern | //+------------------------------------------------------------------+ // provide a way to access the elements of an aggregate object // sequentially without exposing its underlying representation //+------------------------------------------------------------------+ //| applicability | //+------------------------------------------------------------------+ // access an aggregate object's contents without exposing its // internal representation // support multiple traversals of aggregate objects // provide a uniform interface for traversing different aggregate // structures (that is, to support polymorphic iteration) //+------------------------------------------------------------------+ //| structure | //+------------------------------------------------------------------+ // // | Aggregate |<------|Client|------->| Iterator | // |----------------| |-------------| // |CreateIterator()| |First() | // ^ |Next() | // | |IsDone() | // | |CurrentItem()| // | ^ // | | //| Concrete |- - - - - - - ->|Concrete| //| Aggregate |<---------------|Iterator| //|----------------------------------| //|CreateIterator() | //| return new ConcreteIterator(this)| // //+------------------------------------------------------------------+ //| participants | //+------------------------------------------------------------------+ // iterator // defines an interface for accessing and traversing elements // aggregate // defines an interface for creating an iterator object // concrete iterator // implements the iterator interface // keeps track of the current position in the traversal of the // aggregate // concrete aggregate // implements the iterator creation interface to return an // instance of the proper concrete iterator //+------------------------------------------------------------------+ //| collaborations | //+------------------------------------------------------------------+ // a concrete iterator keeps track of the current object in the // aggregate and can compute the succeeding object in the traversal | //---iterator participants #include <Mqh201021_104101.mqh> //iterator #include <Mqh201021_104329.mqh> //aggregate #include <Mqh201021_104505.mqh> //concrete iterator #include <Mqh201021_104755.mqh> //concrete aggregate //--- void OnStart() { Aggregate<string>* aggregate=new ConcreteAggregate; aggregate+="element a"; aggregate+="element b"; aggregate+="element c"; aggregate+="element d"; //--- Iterator<string>* iterator=aggregate.CreateIterator(); for(iterator.First(); !iterator.IsDone(); iterator.Next()) { Print(iterator.CurrentItem()); } //--- delete aggregate; delete iterator; } //+------------------------------------------------------------------+ //| output | //+------------------------------------------------------------------+ // first iteration of aggregate // element a // next iteration of aggregate // element b // next iteration of aggregate // element c // next iteration of aggregate // element d //+------------------------------------------------------------------+ //| consequences | //+------------------------------------------------------------------+ // it supports variations in the traversal of an aggregate // to change the traversal algorithm just replace the iterator // instance with a different one // you can also define iterator subclasses to support new traversals // iterators simplify the aggregate interface // more than one traversal can be pending on an aggregate //+------------------------------------------------------------------+ //| implementation | //+------------------------------------------------------------------+ // who controls the iteration? // who defines the traversal algorithm? // how robust is the iterator? // additional iterator operations // using polymorphic iterators in c++ // iterators may have privileged access // iterators for composites // null iterators //+------------------------------------------------------------------+