0
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.Iniciado por Eslopes
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.COBOL Código:
IDENTIFICATION DIVISION. PROGRAM-ID. MAIN AS "ConsoleApplication1.Main". ENVIRONMENT DIVISION. CONFIGURATION SECTION. SPECIAL-NAMES. REPOSITORY. class ClassConcreteAggregate as "IteratorPattern.ConcreteAggregate" class ClassConcreteIterator as "IteratorPattern.ConcreteIterator" class ClassObject as "System.Object" class ClassSystemConsole as "System.Console". DATA DIVISION. WORKING-STORAGE SECTION. 01 array usage object reference ClassConcreteAggregate. 01 item usage object reference ClassObject. 01 iteratorusage object reference ClassConcreteIterator. PROCEDURE DIVISION. invoke ClassConcreteAggregate "NEW" returning array invoke array "SetItem" using 0 "Item a" invoke array "SetItem" using 1 "Item b" invoke array "SetItem" using 2 "Item c" invoke array "SetItem" using 3 "Item d" invoke ClassConcreteIterator "NEW" using array returning iterator display "Iterating over collection:" set item to iterator::"First"() perform until item = null invoke ClassSystemConsole "WriteLine" using item set item to iterator::"Next"() end-perform 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:
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.COBOL Código:
CLASS-ID. ConcreteAggregate as "IteratorPattern.ConcreteAggregate" inherits ClassAbstractAggregate. environment division. configuration section. repository. class ClassAbstractAggregate as "IteratorPattern.AbstractAggregate" class ClassAbstractIterator as "IteratorPattern.Iterator" class ClassConcreteIterator as "IteratorPattern.ConcreteIterator" class ClassArrayList as "System.Collections.ArrayList" class ClassObject as "System.Object" property ArrayCount as "Count". object. data division. working-storage section. copy "Types.Book". 01 _items usage object reference ClassArrayList. procedure division. method-id. NEW. procedure division. invoke ClassArrayList "NEW" returning _items end method NEW. method-id. CreateIterator as "CreateIterator" override. data division. linkage section. 01 outIterator usage object reference ClassAbstractIterator. procedure division returning outIterator. invoke ClassConcreteIterator "NEW" using SELF returning outIterator end method CreateIterator. method-id. CountItems as "Count". data division. linkage section. 01 outCount type SystemInt32. procedure division returning outCount. move ArrayCount of _items to outCount end method CountItems. method-id. GetItem as "GetItem". data division. linkage section. 01 inIndex type SystemInt32. 01 outObject usage object reference ClassObject. procedure division using inIndex returning outObject. invoke _items "Get_Item" using inIndex returning outObject end method GetItem. method-id. SetItem as "SetItem". data division. linkage section. 01 inIndextype SystemInt32. 01 inObject usage object reference ClassObject. procedure division using inIndex inObject. invoke _items "Insert" using inIndex inObject end method SetItem. end object. 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):COBOL Código:
CLASS-ID. ConcreteIterator as "IteratorPattern.ConcreteIterator" inherits ClassAbstractIterator. environment division. configuration section. repository. class ClassObject as "System.Object" class ClassAbstractIterator as "IteratorPattern.Iterator" class ClassConcreteAggregate as "IteratorPattern.ConcreteAggregate". object. data division. working-storage section. copy "types.book". 01 _currenttype SystemInt32. 01 _aggregate usage object reference ClassConcreteAggregate private. procedure division. method-id. NEW. data division. linkage section. 01 inAggregate usage object reference ClassConcreteAggregate. procedure division using inAggregate. set _aggregate to inAggregate end method NEW. method-id. FirstItem as "First" override. data division. linkage section. 01 outItem usage object reference ClassObject. procedure division returning outItem. move zeros to _current set outItem to _aggregate::"GetItem"(0) end method FirstItem. method-id. NextItem as "Next" override. data division. linkage section. 01 outItem usage object reference ClassObject. procedure division returning outItem. if (_current < _aggregate::"Count"() - 1) add 1 to _current set outItem to _aggregate::"GetItem" (_current) end-if end method NextItem. method-id. CurrentItem as "CurrentItem" override. data division. linkage section. 01 outItem usage object reference ClassObject. procedure division returning outItem. set outItem to _aggregate::"GetItem"(_current) end method CurrentItem. method-id. IsDone as "IsDone" override. data division. linkage section. 01 outStatus pic 1. *> boolean procedure division returning outStatus. if (_current >= _aggregate::"Count"()) move B"1" to outStatus else move B"0" to outStatus end-if end method IsDone. end object. 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 :COBOL Código:
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:COBOL Código:
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
Cool things with OO Cobol - Source Code
Some references in the web
Iterator .NET Design Pattern in C# and VB - dofactory.com
Iterator - Wikipedia
Marcadores