Iterator mode (iterator pattern) from terrylee)

Source: Internet
Author: User

Overview

In object-oriented software design, we often encounter a class of collection objects. The internal structure of these collection objects may have various implementations, but in conclusion, there are only two points of attention: one is the internal data storage structure of the set, and the other is to traverse the data inside the set. One of the principles of object-oriented design is the single responsibility principle of classes. Therefore, we should try our best to break down these responsibilities and use different classes to assume different responsibilities. The iterator mode separates the traversal behavior of the set object and abstracts an iterator class to take charge of it, so that the internal structure of the set is not exposed, in addition, external code can transparently access the internal data of the set.

Intention

Provides a method to access each element in an aggregate object sequentially without exposing the internal representation of the object. [Gof design patterns]

Structure chart

The iterator mode structure is as follows:

Figure 1 iterator mode structure

Examples in life

The iterator provides a way to access each element in a set object sequentially without exposing the internal representation of the object. In early television sets, a dial was used to change the channel. When changing the channel, you need to manually turn the dial to move through each channel, regardless of whether the channel has a signal. For the current TV set, use the [next] and [previous] buttons. When you press the [next] button, it switches to the next preset channel. Imagine watching TV in a hotel in a strange city. When a channel is changed, it is not the channels but the program content. If you are not interested in a channel program, you can switch to another channel without knowing how many channels it is.

Figure 2 iterator pattern object graph using selector as an Example

IteratorMode description

In object-oriented software design, we often encounter a class of collection objects. The internal structure of these collection objects may have various implementations, but in conclusion, there are only two points of attention: one is the internal data storage structure of the set, and the other is to traverse the data inside the set. One of the principles of object-oriented design is the single responsibility principle of classes. Therefore, we should try our best to break down these responsibilities and use different classes to assume different responsibilities. The iterator mode separates the traversal behavior of the set object and abstracts an iterator class to take charge of it, so that the internal structure of the set is not exposed, in addition, external code can transparently access the internal data of the set. The following is a simple schematic example. The class structure is as follows:

Figure 3 sample code structure

First, there is an abstract aggregation. The so-called aggregation is the collection of data, which can be accessed cyclically. It has only one method getiterator () for sub-classes to implement and obtain an iterator object.

/// <Summary>

/// Abstract Aggregation

/// </Summary>

Public interface ilist

{
Iiterator getiterator ();
}

The abstract iterator is used to access clustering classes and encapsulate some methods to read the aggregated data in order. There are several methods for sub-classes to implement movenext (), currentitem (), Fisrt (), and next.

/// <Summary>

/// Abstract iterator

/// </Summary>

Public interface iiterator
{
Bool movenext ();

Object currentitem ();

Void first ();

Void next ();
}

The specific aggregation implements the unique method in the abstract aggregation and stores a set of data. Here we add the Length attribute and getelement () the method is to facilitate access to the data in the aggregation.

/// <Summary>

/// Specific aggregation

/// </Summary>

Public class concretelist: ilist
{
Int [] list;

Public concretelist ()

{
List = new int [] {1, 2, 3, 4, 5 };
}

Public iiterator getiterator ()

{
Return new concreteiterator (this );
}

Public int Length

{
Get {return list. length ;}
}

Public int getelement (INT index)

{
Return list [Index];
}
}

The specific iterator implements four methods in the abstract iterator. In its constructor, it needs to accept a specific clustering type parameter, here we can write different iteration methods based on the actual situation.

/// <Summary>

/// Specific iterator

/// </Summary>

Public class concreteiterator: iiterator

{
Private concretelist list;

Private int index;

Public concreteiterator (concretelist List)

{
This. List = List;

Index = 0;
}

Public bool movenext ()

{
If (index <list. length)

Return true;

Else

Return false;
}

Public object currentitem ()

{
Return list. getelement (INDEX );
}

Public void first ()

{
Index = 0;
}

Public void next ()

{
If (index <list. length)

{
Index ++;
}
}
}

Simple client program call:

/// <Summary>

/// Client program

/// </Summary>

Class Program

{
Static void main (string [] ARGs)

{
Iiterator iterator;

Ilist list = new concretelist ();

Iterator = List. getiterator ();

While (iterator. movenext ())

{
Int I = (INT) iterator. currentitem ();
Console. writeline (I. tostring ());

Iterator. Next ();
}

Console. Read ();

}

}

An example of a simple iterator is over, and we have not used any of them here. NET features. in C #, it is no longer necessary to implement the iterator mode. The C # language itself has some specific implementations.

. NetIterator mode in

The iterator mode is implemented in. net. The clustering interface and the iterator interface already exist. ienumerator plays the role of the iterator. Its implementation is as follows:

Public interface ieumerator

{
Object current
{
Get;
}

Bool movenext ();

Void reset ();

}

Attribute current returns the elements in the current set. The reset () method restores the position pointed to by initialization. the return value of movenext () is true, indicating that the iterator is successfully moved forward to the next element in the set, the returned value "false" indicates that it is already at the end of the set. The Set object that can provide element traversal implements the ienumerator interface in. net.

Ienumerable assumes the abstract aggregation role and has only one getenumerator () method. This interface must be implemented if the collection object needs to have the fall generation traversal function.

Public interface ienumerable

{
Ieumerator getenumerator ();
}

The following is an example of an iterator in. net1.1. The person class is an enumerable class. The personsenumerator class is an enumerator class. This example is from http://www.theserverside.net/, which was simply modified by me.

Public class persons: ienumerable

{
Public String [] m_names;

Public persons (Params string [] Names)
{
M_names = new string [names. Length];

Names. copyto (m_names, 0 );
}

Private string this [int Index]
{
Get
{
Return m_names [Index];
}

Set
{
M_names [Index] = value;
}
}

Public ienumerator getenumerator ()
{
Return new personsenumerator (this );
}
}

Public class personsenumerator: ienumerator
{
Private int Index =-1;

Private persons P;

Public personsenumerator (persons P)
{
This. P = P;
}

Public bool movenext ()
{
Index ++;

Return index <p. m_names.length;
}

Public void reset ()
{
Index =-1;
}

Public object current
{
Get

{
Return P. m_names [Index];
}
}
}

Let's look at the call of the client code:

Class Program
{
Static void main (string [] ARGs)
{
Persons arrpersons = new persons ("micel", "Christine", "Mathieu", "Julien ");

Foreach (string s in arrpersons)

{
Console. writeline (s );
}

Console. Readline ();
}
}

The program will output:

Micel

Christine

Mathieu

Julien

Now we analyze what the compiler did when executing the foreach statement. The code it executed is roughly as follows:

Class Program

{
Static void main (string [] ARGs)
{
Persons arrpersons = new persons ("micel", "Christine", "Mathieu", "Julien ");

Ienumerator E = arrpersons. getenumerator ();

While (E. movenext ())
{
Console. writeline (string) E. Current );

}

Console. Readline ();
}
}

We can see that this code is very similar to the sample code we mentioned above. At the same time, in this example, we spend most of our energy on implementing the iterator and the class that can be iterated. under net2.0, with the yield return keyword, the implementation will be simpler and more elegant. Next we will re-implement the example in section 2.0:

Public class persons: ienumerable
{
String [] m_names;

Public persons (Params string [] Names)
{
M_names = new string [names. Length];

Names. copyto (m_names, 0 );
}

Public ienumerator getenumerator ()
{
Foreach (string s in m_names)
{
Yield return S;
}
}
}

Class Program
{
Static void main (string [] ARGs)
{
Persons arrpersons = new persons ("micel", "Christine", "Mathieu", "Julien ");

Foreach (string s in arrpersons)
{
Console. writeline (s );
}

Console. Readline ();
}
}

The program will output:

Micel

Christine

Mathieu

Julien

The implementation of the same function is very simple because of the yield return keyword. Okay, so much about the iterator mode in. net. For more details, refer to relevant materials.

Results and key points of implementation

1. Iterative Abstraction: access the content of an aggregate object without exposing its internal representation.

2. Iterative polymorphism: provides a unified interface for Traversing different set structures, so that the same algorithm can be operated on different set structures.

3. robustness of the iterator: Changing the collection structure of the iterator while traversing will cause problems.

Applicability

1. Access the content of an aggregate object without exposing its internal representation.

2. Supports multiple traversal of aggregate objects.

3. provides a unified interface (supporting multi-state iteration) for Traversing different aggregation structures ).

Summary

The iterator mode separates the traversal behavior of the set object and abstracts an iterator class to take charge of it, so that the internal structure of the set is not exposed, in addition, external code can transparently access the internal data of the set.

References

Erich Gamma, design pattern: Basis for reusable object-oriented software, Mechanical Industry Press

Robert C. Martin, Agile Software Development: Principles, models and practices, Tsinghua University Press

Min Hong, Java and mode, e-Industry Press

Alan shalloway James R. Trott, design patterns explained, China Power Publishing House

C # object-oriented design patterns (18): iterator pattern (behavior pattern) by msdn webcast

Author: terrylee
Source: http://terrylee.cnblogs.com

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.