mirror of
https://github.com/farcasclaudiu/design_pattens.git
synced 2026-06-22 05:01:30 +03:00
iterator design pattern
This commit is contained in:
+3
-1
@@ -16,6 +16,7 @@ using design_patterns.structural.flyweight;
|
||||
using design_patterns.structural.proxy;
|
||||
using design_patterns.behavioral.chainofresponsability;
|
||||
using design_patterns.behavioral.command;
|
||||
using design_patterns.behavioral.iterator;
|
||||
|
||||
namespace design_patterns
|
||||
{
|
||||
@@ -45,7 +46,8 @@ namespace design_patterns
|
||||
|
||||
// behavioral
|
||||
// await ChainOfResponsabilitySample.Run();
|
||||
await CommandSample.Run();
|
||||
// await CommandSample.Run();
|
||||
await IteratorSample.Run();
|
||||
}
|
||||
catch (System.Exception ex)
|
||||
{
|
||||
|
||||
@@ -0,0 +1,122 @@
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Linq;
|
||||
using System.Collections.Generic;
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace design_patterns.behavioral.iterator
|
||||
{
|
||||
/// <summary>
|
||||
/// Iterator is a behavioral design pattern that lets you traverse elements
|
||||
/// of a collection without exposing its underlying representation
|
||||
/// (list, stack, tree, etc.).
|
||||
///
|
||||
/// Use it:
|
||||
/// - when your collection has a complex data structure under the hood,
|
||||
/// but you want to hide its complexity from clients.
|
||||
/// - to reduce duplication of the traversal code across your app.
|
||||
/// - when you want your code to be able to traverse different data structures
|
||||
/// or when types of these structures are unknown beforehand.
|
||||
/// </summary>
|
||||
public class IteratorSample
|
||||
{
|
||||
public static async Task Run()
|
||||
{
|
||||
Console.WriteLine("Behavioral - Iterator");
|
||||
|
||||
var boss = new Employee() { Name = "Boss" };
|
||||
var emp1 = new Employee { Name = "Employee 1" };
|
||||
boss.AddUnder(emp1);
|
||||
emp1.AddUnder(new Employee { Name = "Emp 1.1"});
|
||||
emp1.AddUnder(new Employee { Name = "Emp 1.2"});
|
||||
var emp13 = new Employee { Name = "Emp 1.3"};
|
||||
emp1.AddUnder(emp13);
|
||||
emp13.AddUnder(new Employee { Name = "Emp 1.3.1"});
|
||||
emp13.AddUnder(new Employee { Name = "Emp 1.3.2"});
|
||||
emp13.AddUnder(new Employee { Name = "Emp 1.3.3"});
|
||||
emp1.AddUnder(new Employee { Name = "Emp 1.4"});
|
||||
var emp2 = new Employee { Name = "Employee 2" };
|
||||
boss.AddUnder(emp2);
|
||||
emp2.AddUnder(new Employee { Name = "Emp 2.1"});
|
||||
|
||||
var custEnum = new Organisation(boss);
|
||||
foreach(var emp in custEnum)
|
||||
Console.WriteLine($"employee {emp.Name}");
|
||||
}
|
||||
|
||||
public class Employee {
|
||||
public string Name { get; set; }
|
||||
public Employee Boss { get; set; }
|
||||
public List<Employee> Underlings = new List<Employee>();
|
||||
|
||||
public void AddUnder(Employee employee)
|
||||
{
|
||||
Underlings.Add(employee);
|
||||
employee.Boss = this;
|
||||
}
|
||||
}
|
||||
|
||||
public class Organisation {
|
||||
private Employee root;
|
||||
|
||||
public Organisation(Employee root)
|
||||
{
|
||||
this.root = root;
|
||||
}
|
||||
|
||||
// enumerator method to iterate in the hierarchy
|
||||
public OrganisationIterator GetEnumerator() {
|
||||
return new OrganisationIterator(root);
|
||||
}
|
||||
}
|
||||
|
||||
public class OrganisationIterator {
|
||||
|
||||
private Employee root;
|
||||
|
||||
public OrganisationIterator(Employee root) {
|
||||
this.root = root;
|
||||
this.Current = root;
|
||||
}
|
||||
|
||||
// Current property is mandatory
|
||||
public Employee Current { get; set; }
|
||||
|
||||
private bool yieldStarted;
|
||||
private Dictionary<int, int> idx = new Dictionary<int, int>();
|
||||
|
||||
// MoveNext method is mandatory
|
||||
public bool MoveNext() {
|
||||
if(!yieldStarted){
|
||||
Current = root;
|
||||
yieldStarted = true;
|
||||
return true;
|
||||
}
|
||||
position1:
|
||||
var currentKey = Current.GetHashCode();
|
||||
if(!idx.ContainsKey(currentKey)){
|
||||
idx[currentKey] = -1;
|
||||
}
|
||||
if(Current.Underlings!=null) {
|
||||
if(Current.Underlings.Count>(idx[currentKey]+1)) {
|
||||
idx[currentKey] += 1;
|
||||
Current = Current.Underlings[idx[currentKey]];
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if(Current.Boss!=null)
|
||||
{
|
||||
Current = Current.Boss;
|
||||
goto position1;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public void Reset() {
|
||||
Current = root;
|
||||
idx.Clear();
|
||||
yieldStarted = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user