1 / 15

Iterators

Iterators. Object Behavioral. T.J. Niglio Computer & Systems Engineering. Fall 2003 Software Design & Documentation. Where is the need?. Method of accessing an object’s elements without exposing internal structure.

jpulido
Télécharger la présentation

Iterators

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Iterators Object Behavioral T.J. Niglio Computer & Systems Engineering Fall 2003 Software Design & Documentation

  2. Where is the need? • Method of accessing an object’s elements without exposing internal structure. • Want a compact way to keep tract of which elements have already been accessed, as well as what is the current element. • Might require different traversal properties (Filtering).

  3. How does it work?

  4. How do I make one? • Cannot simply instantiate a specific iterator class. So what do you do? • Make the aggregate object responsible for the creation of its own concrete iterator. • Requires operation such as CreateIterator through which clients request an iterator object.

  5. So what can I do now? • Support variations in the traversals of an aggregate. (e.g. traversing a parse tree can be done inorder or preorder) • Makes the aggregate’s life simpler. No need to provide position calculation code into your aggregate anymore. • Multiple simultaneous traversals are allowed. Since the ConcreteIterator is an instance of the Abstract Iterator Class, multiple instances will each track their own progress & position.

  6. Implementation FAQs • Who controls the iteration? • External Iterator – When the client has control • Client must advance the iterator • More flexible than internal iterators for operations such as comparisons. • Internal Iterator – When the iterator has control • The iterator can be given an operation which it could apply to each element in the aggregate. • Easier than External Iterators because iteration logic is defined for you.

  7. Implementation FAQs 2. Who defines the traversal algorithm? Aggregate - Traversal algorithm can be part of the aggregate therefore only using the iterator as a placeholder (Cursor). Iterator - Easy to switch algorithms on the same aggregate, or reuse traversal code on other aggregates. Might violate the encapsulation of the aggregate if iterator needs access to private variables within the aggregate.

  8. Implementation FAQs 3. How robust is the iterator? • Dangerous to modify an aggregate while traversing. • A robust iterator ensure that insertions and removals don’t interfere with traversal. • Doesn’t need to copy the aggregate • Must be registered with the aggregate so that insertions or removals will adjust the internal state of the iterator. • Or, traversal information can be maintained internally by the aggregate.

  9. Implementation FAQs 4. Any additional iterator operations? Minimum required operations: First, Next, IsDone, and CurrentItem Optional useful operations: Previous – Positions the iterator to the previous item. SkipTo – Useful for sorted or indexed collections. Can skip to an object matching certain criteria.

  10. Implementation FAQs 5. Using polymorphic iterators in C++ Iterator object must be allocated dynamically by a factory method. Polymorphic: Allows you to change the aggregate class without changing the client code. Factory Method: Lets a class defer instantiation to subclasses. Difficult to implement in C++ for many reasons including: client is responsible for deleting the iterator (error-prone especially when there are multiple exit points); Can be remedied using the Proxy Pattern.

  11. Implementation FAQs 6. Iterators may have privileged access. Iterator can be viewed as an extention of the aggregate that created it. Known as a friend of the aggregate. Such a relationship makes defining multiple traversals difficult because of the creation of multiple friends of the aggregate. Remedy: to allow the iterator access to protected operations for accessing important but publicly unavailable members of the aggregate.

  12. Implementation FAQs 7. How are iterators used for composites? External iterators are difficult to implement over recursive aggregate structures like composites. The path to the current position must be stored. Internal Iterators can record the current position by calling itself recursively thereby storing the path implicitly in the call stack. If the nodes of a composite already have an interface for moving between siblings, parents, and children, a cursor based iterator would be better to just keep record of the current position.

  13. Implementation FAQs 8. What about Null iterators? NullIterator: degenerate iterator that’s helpful for handling boundary conditions. Always done with traversal – IsDone operation always evaluates to true. Used to traverse tree-structured aggregates. At each position, the current element creates an iterator for its children. Aggregate elements return a concrete iterator as normal, but leaf elements return an instance of NullIterator making the implementation uniform.

  14. Sample Code Abstract Iterator Class Interface Template <class Item> class Iterator { Public: virtual void First() = 0; virtual void Next() = 0; virtual bool IsDone() const = 0; virtual Item CurrentItem() const = 0; Protected: Iterator(); }

  15. Sample Code Using iterators to make printing easier Suppose you had a List of Employees with the employees class support the Print() operation. To print the list, you can define a PrintEmployees operation that takes an iterator as an argument: Void PrintEmployees (Iterator<Employee*>& i) { for(i.First(); !i.IsDone(); i.Next()) { i.CurrentItem()->Print(); } }

More Related