Register  Login
OO Cobol Examples » Design Patterns » Iterator
 

Iterator

"Next! Next! Next! Next!"

Iterator

An iterator is a way to traverse a collection of objects without care about underline details. So, if you have a collection of strings, or a collections of Customers, or even a collection of records and all that you want to do is to get one by one sequentially using a unified model, what you need is an iterator.


UML diagram

 

The diagram above depict the basic idea of an iterator. A client class (or just a procedural program) creates a collection using ConcreteAggregate class, then an Iterator is created receiving the newly created collection. The iterator allows you to retrieve each element in the collection ordered by the index.

There are too many uses for iterators, including using the collection to hold data from a database query, and the iterator to taverse that collection when generating a report, for example.

Code

Lets see some action. Below is the code that use the iterator: 

 1:         IDENTIFICATION DIVISION.
 2:         PROGRAM-ID. MAIN AS "ConsoleApplication1.Main".
 3:         ENVIRONMENT DIVISION.
 4:         CONFIGURATION SECTION.
 5:         SPECIAL-NAMES.
 6:         REPOSITORY.
 7:                 class  ClassConcreteAggregate as "IteratorPattern.ConcreteAggregate"
 8:                 class  ClassConcreteIterator  as "IteratorPattern.ConcreteIterator"
 9:                 class  ClassObject            as "System.Object"
 10:                class  ClassSystemConsole     as "System.Console".
 11:                  
 12:         DATA DIVISION.
 13:         WORKING-STORAGE SECTION.
 14:         01 array      usage object reference ClassConcreteAggregate.
 15:         01 item     usage object reference ClassObject.
 16:         01 iteratorusage object reference ClassConcreteIterator.
 17:        
 18:         PROCEDURE DIVISION.
 19:             invoke ClassConcreteAggregate "NEW" returning array
 20:            
 21:             invoke array "SetItem" using 0 "Item a"
 22:             invoke array "SetItem" using 1 "Item b"
 23:             invoke array "SetItem" using 2 "Item c"
 24:             invoke array "SetItem" using 3 "Item d"
 25:             invoke ClassConcreteIterator "NEW" using array returning iterator
 26:            
 27:             display "Iterating over collection:"  
 28:            
 29:             set    item      to  iterator::"First"()
 30:            
 31:           perform until item = null
 32:                     invoke ClassSystemConsole "WriteLine" using item
 33:                    
 34:                     set  item    to  iterator::"Next"()
 35:           end-perform
 36:       END PROGRAM MAIN.
 

Running the code above a collection is created with four strings, but it could be anything. The iteration occurs within the PERFORM verb block. The result is the following:

Item a
Item b
Item c
Item d

The ConcreteAggregate class contains the collection created with the "SetItem" method. That collection is an ArrayList object, so the element can be anything (alphanumeric items, numeric, numeric edited, objects, anything). An element can also be updated through the very same SetItem method.

 

 1:  CLASS-ID. ConcreteAggregate as "IteratorPattern.ConcreteAggregate"   inherits ClassAbstractAggregate.
 2:      environment division.
 3:          configuration section.
 4:              repository.
 5:                  class  ClassAbstractAggregate          as  "IteratorPattern.AbstractAggregate"
 6:                  class  ClassAbstractIterator           as  "IteratorPattern.Iterator"
 7:                  class  ClassConcreteIterator           as  "IteratorPattern.ConcreteIterator"
 8:                  class  ClassArrayList                  as  "System.Collections.ArrayList"
 9:                  class  ClassObject                     as  "System.Object"
 10:                  
 11:                 property ArrayCount                    as  "Count".
 12:      
 13:      object.                            
 14:          data division.
 15:              working-storage section.
 16:              copy "Types.Book".
 17:              
 18:              01   _items    usage object reference ClassArrayList.
 19:              
 20:              
 21:          procedure division.
 22:              method-id. NEW.
 23:                  procedure division.
 24:                      invoke ClassArrayList "NEW" returning _items
 25:                      
 26:              end method NEW.
 27:              
 28:              method-id. CreateIterator as "CreateIterator" override.  
 29:                  data division.
 30:                      linkage section.
 31:                      01    outIterator  usage object reference ClassAbstractIterator.
 32:                  
 33:                  procedure division returning outIterator.
 34:                      invoke ClassConcreteIterator "NEW" using SELF returning outIterator
 35:                      
 36:              end method CreateIterator.
 37:              
 38:              method-id. CountItems as "Count".  
 39:                  data division.
 40:                      linkage section.
 41:                      01    outCount  type SystemInt32.
 42:                  
 43:                  procedure division returning outCount.
 44:                      move  ArrayCount of _items     to  outCount
 45:                      
 46:              end method CountItems.
 47:              
 48:              method-id. GetItem as "GetItem".
 49:                  data division.
 50:                      linkage section.
 51:                      01    inIndex    type SystemInt32.
 52:                      01    outObject  usage object reference ClassObject.
 53:                  
 54:                  procedure division using inIndex returning outObject.
 55:                      
 56:                      invoke _items "Get_Item" using inIndex returning outObject
 57:              
 58:              end method GetItem.
 59:              method-id. SetItem as "SetItem".
 60:                  data division.
 61:                      linkage section.
 62:                      01    inIndextype  SystemInt32.
 63:                      01    inObject  usage object reference ClassObject.
 64:                  
 65:                  procedure division using inIndex inObject.
 66:                      
 67:                      invoke _items "Insert" using inIndex inObject
 68:                      
 69:              end method SetItem.
 70:              
 71:      end object.        
 72:  END CLASS ConcreteAggregate.

This pattern implementation requires the index of the item, but you could get rid of it by controlling it internally. It is up to you!

Next we got the Iterator class that is created receiving the collection represented by the "array" variable (ConcreteAggregate):
 

 1:  CLASS-ID. ConcreteIterator as "IteratorPattern.ConcreteIterator"  inherits ClassAbstractIterator.
 2:      environment division.
 3:          configuration section.
 4:              repository.
 5:                  class  ClassObject            as "System.Object"
 6:                  class  ClassAbstractIterator  as "IteratorPattern.Iterator"
 7:                  class  ClassConcreteAggregate as "IteratorPattern.ConcreteAggregate".
 8:      
 9:      object.             
 10:          data division.
 11:              working-storage section.
 12:                  copy "types.book".
 13:                  
 14:                  01 _currenttype SystemInt32.
 15:                  01 _aggregate usage object reference ClassConcreteAggregate private.
 16:          procedure division.
 17:              method-id. NEW.
 18:                  data division.
 19:                      linkage section.
 20:                      01    inAggregate  usage object reference ClassConcreteAggregate.
 21:                      
 22:                  procedure division using inAggregate.
 23:                      set    _aggregate      to  inAggregate
 24:                      
 25:              end method NEW.
 26:              
 27:              method-id. FirstItem as "First" override. 
 28:                  data division.
 29:                      linkage section.
 30:                      01    outItem  usage object reference ClassObject.
 31:                  
 32:                  procedure division returning outItem.
 33:                      move  zeros     to  _current
 34:                  
 35:                      set   outItem   to  _aggregate::"GetItem"(0)
 36:                  
 37:              end method FirstItem.
 38:              
 39:              method-id. NextItem as "Next" override. 
 40:                  data division.
 41:                      linkage section.
 42:                      01    outItem  usage object reference ClassObject.
 43:                  
 44:                  procedure division returning outItem.
 45:                      if (_current < _aggregate::"Count"() - 1)
 46:                          add  1         to  _current
 47:                          set  outItem   to  _aggregate::"GetItem" (_current)  
 48:                      end-if
 49:              end method NextItem.
 50:              
 51:              method-id. CurrentItem as "CurrentItem" override. 
 52:                  data division.
 53:                      linkage section.
 54:                      01    outItem  usage object reference ClassObject.
 55:                  
 56:                  procedure division returning outItem.
 57:                      
 58:                      set   outItem  to  _aggregate::"GetItem"(_current)
 59:         
 60:                  
 61:              end method CurrentItem.
 62:              
 63:              method-id. IsDone as "IsDone" override. 
 64:                  data division.
 65:                      linkage section.
 66:                      01    outStatus  pic 1. *> boolean
 67:                  
 68:                  procedure division returning outStatus.
 69:                  
 70:                      if (_current >= _aggregate::"Count"())
 71:                       move   b"1"     to  outStatus
 72:                      else
 73:                       move   b"0"     to  outStatus
 74:                      end-if
 75:                                   
 76:              end method IsDone.
 77:              
 78:      end object.       
 79:  END CLASS ConcreteIterator.

The Iterator Pattern has immediate usage in your application. It is a way to implement a "foreach" statement in Cobol, but as a matter of fact it is not the only way to do this! You can also use the PERFORM verb :

                     PERFORM VARYING identifier-1 THROUGH identifier-2

                     END-PERFORM

Identifier-1 must be a data item.
Identifier-2 must be a object-identifier that identifies a data collection. However, it must not be a predefined object identifier.

The type of the object identifier specified for identifier-2 must be one of the following:
a. A type that implements the System.Collections.IEnumerable interface.
b. A type that implements the System.Collections.Generic.IEnumerable interface.
c. A type that satisfies the following conditions:

- The type has an accessible instance method named GetEnumerator. The GetEnumerator method does not have arguments and returns a type T.

- The type T that contains the accessible instance method named MoveNext.

The MoveNext method does not have arguments and returns a Boolean type.

- The type T contains the accessible instance property named Current. The Current property has a get accessor.

 Example:

           01 aString pic x(20).
           01 collection
usage object reference ClassArrayList.

           invoke ClassArrayList "NEW" returning collection

 

           invoke collection "Add" using "item 1"
           invoke collection "Add" using "item 2"
           invoke collection "Add" using "item 3"
           invoke collection "Add" using "item 4"

 

           perform varying aString through collection
                      display aString
           end-perform

 

 

Download the source

http://cobolrocks.codeplex.com/SourceControl/changeset/view/58694#


Some references in the web

http://www.dofactory.com/Patterns/PatternIterator.aspx
http://en.wikipedia.org/wiki/Iterator

 

 

 
 
 
 
 
Creative Commons License The text of this site is licensed under a Creative Commons License.

 

 

Comments

 Name  
 Email
 Comment  
CAPTCHA image
Enter the code shown above

Sponsors


Terms Of Use | Privacy Statement | Copyright 2009-2010 by RedRailsDynnamite DotNetNuke Skins & Modules