
I am a software engineer with over 10 years of experience in a huge variety of projects and architectures, some simple others considerably complex.
Some of my main skills include Software Architecture, Web Development, ASP.NET Core, React.js, Entity Framework Core, Javascript, SQL and Web Services.
I consider myself passionate about coding as I really fell excited about learning technologies and using them to automate and improve processes.
Objective 🎯
Provide a way to access elements of a list sequentially without exposing its underlying representation.
Type ✅
✔️Behavioral: Describes how objects interact/communicate between themselves.
❌Creational: Describes how to instantiate an object without large and complex.
❌Structural: Describes how objects/classes are composed to form larger structures.
UML 📐

Participants 🔗
• Iterator:
- Defines an interface to access elements in the collection
• ConcreteIterator:
- Implements the Iterator interface
- Keeps track of the current position in the traversal of the collection
• Aggregate:
- Defines the interface of the Iterator object that will manipulate the collection
• ConcreteAggregate:
- Responsible for maintaining the real list of objects that will be manipulated
- Implements the Aggregate interface and its method to return a ConcreteIterator
Notes 📝
• In the ConcreteAggregate object, an Indexer must be implemented to avoid external manipulation to the list items.
Sample Code 🎮
Structural Example 🏛️

public static class IteratorStructural
{
public static void Execute()
{
ConcreteAggregate lConcreteAggregate = new ConcreteAggregate();
lConcreteAggregate[0] = "Item A";
lConcreteAggregate[1] = "Item B";
lConcreteAggregate[2] = "Item C";
lConcreteAggregate[3] = "Item D";
// Create Iterator and provide aggregate
ConcreteIterator lConcreteIterator = new ConcreteIterator(lConcreteAggregate);
Console.WriteLine("Iterating over collection:");
object lobject = lConcreteIterator.First();
while (lobject != null)
{
Console.WriteLine(lobject);
lobject = lConcreteIterator.Next();
}
}
}
public abstract class Aggregate
{
public abstract Iterator CreateIterator();
}
public class ConcreteAggregate : Aggregate
{
private ArrayList _Items = new ArrayList();
public override Iterator CreateIterator()
{
return new ConcreteIterator(this);
}
public int Count
{
get { return _Items.Count; }
}
public object this[int prIndex]
{
get { return _Items[prIndex]; }
set { _Items.Insert(prIndex, value); }
}
}
public abstract class Iterator
{
public abstract object First();
public abstract object Next();
public abstract bool IsDone();
public abstract object CurrentItem();
}
public class ConcreteIterator : Iterator
{
private ConcreteAggregate _ConcreteAggregate;
private int _CurrentElement = 0;
public ConcreteIterator(ConcreteAggregate prConcreteAggregate)
{
_ConcreteAggregate = prConcreteAggregate;
}
public override object First()
{
return _ConcreteAggregate[0];
}
public override object Next()
{
object lResult = null;
if (_CurrentElement < _ConcreteAggregate.Count - 1)
{
lResult = _ConcreteAggregate[++_CurrentElement];
}
return lResult;
}
public override object CurrentItem()
{
return _ConcreteAggregate[_CurrentElement];
}
public override bool IsDone()
{
return _CurrentElement >= _ConcreteAggregate.Count;
}
}
Output

Real-world Example 🔥

public static class IteratorPractical
{
public static void Execute()
{
OfficeFiles lOfficeFiles = new OfficeFiles();
lOfficeFiles[0] = new File() { Name = "File001_PB", IsPrivate = false };
lOfficeFiles[1] = new File() { Name = "File002_PV", IsPrivate = true };
lOfficeFiles[2] = new File() { Name = "File003_PB", IsPrivate = false };
lOfficeFiles[3] = new File() { Name = "File004_PV", IsPrivate = true };
lOfficeFiles[4] = new File() { Name = "File005_PB", IsPrivate = false };
lOfficeFiles[5] = new File() { Name = "File006_PV", IsPrivate = true };
FileIterator lFileIterator = lOfficeFiles.CreateIterator();
Console.WriteLine("Iterating over files using \"Public File Iterator\": ");
File lFile = lFileIterator.First();
Console.WriteLine("First File: " + lFile.Name);
lFile = lFileIterator.Next();
Console.WriteLine("Next File: " + lFile.Name);
List<File> lFiles = lFileIterator.GetAll();
Console.WriteLine("All Files: " + String.Join(", ", lFiles.Select(X => X.Name).ToList()));
lFileIterator = new PrivateFileIterator(lOfficeFiles);
Console.WriteLine("\n\rIterating over files using \"Private File Iterator\": ");
lFile = lFileIterator.First();
Console.WriteLine("First File: " + lFile.Name);
lFile = lFileIterator.Next();
Console.WriteLine("Next File: " + lFile.Name);
lFiles = lFileIterator.GetAll();
Console.WriteLine("All Files: " + String.Join(", ", lFiles.Select(X => X.Name).ToList()));
}
}
// Aggregate (Concrete)
public class OfficeFiles
{
private ArrayList _Items = new ArrayList();
public FileIterator CreateIterator()
{
return new PublicFileIterator(this);
}
public int Count
{
get { return _Items.Count; }
}
public object this[int prIndex]
{
get { return _Items[prIndex]; }
set { _Items.Insert(prIndex, value); }
}
}
// Iterator
public abstract class FileIterator
{
public abstract File First();
public abstract File Next();
public abstract List<File> GetAll();
public abstract File CurrentItem();
}
// Concrete Iterator
public class PublicFileIterator : FileIterator
{
private OfficeFiles _OfficeFiles;
private int _CurrentElement = 0;
public PublicFileIterator(OfficeFiles prOfficeFiles)
{
_OfficeFiles = prOfficeFiles;
this.First(); // To set the correct _CurrentElement
}
public override File First()
{
for (int i = 0; i < _OfficeFiles.Count; i++)
{
if (((File)_OfficeFiles[i]).IsPrivate == false)
{
_CurrentElement = i;
return ((File)_OfficeFiles[_CurrentElement]);
}
}
return null;
}
public override File Next()
{
object lResult = null;
for (int i = _CurrentElement; i < _OfficeFiles.Count; i++)
{
_CurrentElement++;
if (((File)_OfficeFiles[_CurrentElement]).IsPrivate == false)
return ((File)_OfficeFiles[_CurrentElement]);
}
return null;
}
public override List<File> GetAll()
{
List<File> lResult = new List<File>();
for (int i = 0; i < _OfficeFiles.Count; i++)
{
if (((File)_OfficeFiles[i]).IsPrivate == false)
lResult.Add(((File)_OfficeFiles[i]));
}
return lResult;
}
public override File CurrentItem()
{
return ((File)_OfficeFiles[_CurrentElement]);
}
}
// Concrete Iterator
public class PrivateFileIterator : FileIterator
{
private OfficeFiles _OfficeFiles;
private int _CurrentElement = 0;
public PrivateFileIterator(OfficeFiles prOfficeFiles)
{
_OfficeFiles = prOfficeFiles;
_OfficeFiles = prOfficeFiles;
this.First(); // To set the correct _CurrentElement
}
public override File First()
{
for (int i = 0; i < _OfficeFiles.Count; i++)
{
if (((File)_OfficeFiles[i]).IsPrivate == true)
{
_CurrentElement = i;
return ((File)_OfficeFiles[_CurrentElement]);
}
}
return null;
}
public override File Next()
{
object lResult = null;
for (int i = _CurrentElement; i < _OfficeFiles.Count; i++)
{
_CurrentElement++;
if (((File)_OfficeFiles[_CurrentElement]).IsPrivate == true)
return ((File)_OfficeFiles[_CurrentElement]);
}
return null;
}
public override List<File> GetAll()
{
List<File> lResult = new List<File>();
for (int i = 0; i < _OfficeFiles.Count; i++)
{
if (((File)_OfficeFiles[i]).IsPrivate == true)
lResult.Add(((File)_OfficeFiles[i]));
}
return lResult;
}
public override File CurrentItem()
{
return ((File)_OfficeFiles[_CurrentElement]);
}
}
public class File
{
public string Name { get; set; }
public bool IsPrivate { get; set; }
}
Output

Source Code 🎲
https://github.com/VictorLins/DesignPatterns





