Iterator Pattern
The iterator pattern is a behavioral pattern that provides a way to sequentially access elements in an aggregate object without exposing the internal representation of that object, both without exposing the internal structure of the collection and with transparent access to the data inside the collection by external code.
role
1. Iterators
The iterator role is responsible for defining the interface to access and traverse elements;
2. Concrete Iteraror
The concrete iterator role implements the iterator interface and needs to record the current position in the traversal;
3. Aggregate
The aggregation role is responsible for defining the interface to get the iterator role;
4. Concrete Aggregate
The aggregation role interface is implemented.
The sample
The namespace IteratorPattern contains the Person base class, People class, PelpleEnum class, an ApplePhone class, and BestEnum class. The Person example comes from Microsoft’s official IEnumerable interface introduction page, but BestEnum uses it. The Yield Return keyword in Net 2.0 creates a sequence of iPhone messages.
namespace IteratorPattern
Copy the code
Traditional iterator implementation
public class Person {
public string FirstName { get; set; }
public string LastName { get; set; }
public Person(string firstName, string lastName) {
this.FirstName = firstName;
this.LastName = lastName; }}Copy the code
The Person class, which contains First Name and Last Name.
public class People : IEnumerable {
private Person[] _people = null;
public People(Person[] pArray) {
_people = new Person[pArray.Length];
for (int i = 0; i < pArray.Length; i++) { _people[i] = pArray[i]; }}public IEnumerator GetEnumerator() {
return newPeopleEnum(_people); }}Copy the code
People class, implement IEnumerable interface.
public class PeopleEnum : IEnumerator {
private Person[] _people = null;
private int _cursor = - 1;
public PeopleEnum(Person[] list) {
_people = list;
}
public bool MoveNext() {
_cursor++;
return (_cursor < _people.Length);
}
public void Reset() {
_cursor = - 1;
}
public object Current {
get {
try {
return _people[_cursor];
}
catch (IndexOutOfRangeException) {
throw newInvalidOperationException(); }}}}Copy the code
PeopleEnum class, which implements the IEnumerator interface.
Yield Return iterator implementation
The yield keyword indicates to the compiler that the method it is in is an iterator block, and the yield return returns the state machine of an iterator.
public class ApplePhone {
public string PhoneName { get; set; }
public DateTime PublishedDate { get; set; }}Copy the code
ApplePhone class, which contains the phone name and release date.
public class BestEnum {
public static IEnumerable<ApplePhone> GetIPhones() {
yield return new ApplePhone {
PhoneName = "IPhone",
PublishedDate = new DateTime(2007.1.9)};yield return new ApplePhone {
PhoneName = "IPhone 3G",
PublishedDate = new DateTime(2008.6.10)};yield return new ApplePhone {
PhoneName = "IPhone 3GS",
PublishedDate = new DateTime(2009.6.9)};yield return new ApplePhone {
PhoneName = "IPhone 4",
PublishedDate = new DateTime(2010.6.8)};// Some code has been omitted}}Copy the code
The BestEnum class, which contains the sequence of the GetIPhones method that returns the iPhone message.
public class Program {
protected const string LINE_BREAK =
"-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --";
public static void Main(string[] args) {
var peopleArray = new Person[]
{
new Person("John"."Smith"),
new Person("Jim"."Johnson"),
new Person("Sue"."Rabon")};var peopleList = new People(peopleArray);
foreach(Person p in peopleList)
Console.WriteLine(p.FirstName + "" + p.LastName);
Console.WriteLine(LINE_BREAK);
var iterator = peopleList.GetEnumerator();
while(iterator.MoveNext()) {
var person = iterator.Current as Person;
Console.WriteLine(person.FirstName + "" + person.LastName);
}
Console.WriteLine(LINE_BREAK);
foreach(var phone in BestEnum.GetIPhones()) {
Console.WriteLine("[" + phone.PhoneName + "] was released in " +
phone.PublishedDate.ToString("yyyy-MM-dd") + "!"); } Console.WriteLine(LINE_BREAK); Console.ReadKey(); }}Copy the code
This is the caller’s code, and here is the output of the case:
John Smith Jim Johnson Sue Rabon --------------------------------------------- John Smith Jim Johnson Sue Rabon -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -IPhone] was released in 2007- 01- 09!
[IPhone 3G] was released in 2008- 06- 10!
[IPhone 3GS] was released in 2009- 06- 09!
[IPhone 4] was released in 2010- 06- 08!
[IPhone 4s] was released in 2011- 10- 04!
[IPhone 5] was released in 2012- 09- 13!
[IPhone 5S] was released in 2013- 09- 10!
[IPhone 5C] was released in 2013- 09- 10!
[IPhone 6] was released in 2014- 09- 10!
[IPhone 6 Plus] was released in 2014- 09- 10!
[IPhone 6s] was released in 2015- 09- 10!
[IPhone 6s Plus] was released in 2015- 09- 10!
[IPhone 7] was released in 2016- 09- 08!
[IPhone 7 Plus] was released in 2016- 09- 08!
[IPhone 8] was released in 2017- 09- 13!
[IPhone 8 Plus] was released in 2017- 09- 13!
[IPhone X] was released in 2017- 09- 13!
---------------------------------------------
Copy the code
advantages
1. The iterator pattern enables access to the contents of an aggregate object without exposing its internal representation, i.e. iterative abstraction; 2. The iterator pattern provides a unified interface for traversing different collection structures, allowing the same algorithm to operate on different collection structures.
disadvantages
Iterator mode changing the collection structure of the iterator while iterating will cause an exception. So using foreach statements can only iterate over a collection, not change elements in the collection at the same time.
Usage scenarios
1. The system needs to access the contents of an aggregate object without exposing its internal representation; 2. The system needs to support multiple traversal of the aggregate object; 3. The system needs to provide a unified interface for different aggregation structures.