Nội dung
Iterator là một mẫu thiết kế hành vi cho phép duyệt tuần tự thông qua một cấu trúc dữ liệu phức tạp mà không để lộ các chi tiết bên trong của nó.
Nhờ có Iterator, client có thể xem qua các phần tử của các tập hợp khác nhau theo cách tương tự bằng cách sử dụng một giao diện trình lặp duy nhất.
Cách sử dụng mẫu
Sử dụng: Mẫu rất phổ biến trong mã C#. Nhiều framework và thư viện sử dụng nó để cung cấp một cách chuẩn để duyệt qua các tập hợp của chúng.
Nhận dạng: Iterator dễ dàng nhận ra bằng các phương thức điều hướng (chẳng hạn như next, previous và các phương thức khác). Mã client sử dụng trình lặp có thể không có quyền truy cập trực tiếp vào tập hợp đang được duyệt.
Chương trình mẫu
main.cpp
using System;
using System.Collections;
using System.Collections.Generic;
namespace DesignPatterns.Iterator.Conceptual
{
abstract class Iterator : IEnumerator
{
object IEnumerator.Current => Current();
// Trả về key của phần tử hiện tại
public abstract int Key();
// Trả về phần tử hiện tại
public abstract object Current();
// Chuyển đến phần tử kế tiếp
public abstract bool MoveNext();
// Quay lại phần tử đầu tiên
public abstract void Reset();
}
abstract class IteratorAggregate : IEnumerable
{
// Trả về một Iterator hoặc một IteratorAggregate khác
// cho đối tượng triển khai.
public abstract IEnumerator GetEnumerator();
}
// Concrete Iterator hiện thực các thuật toàn duyệt tập hợp khác nhau.
// Các class này luôn lưu trữ vị trí duyệt hiện tại.
class AlphabeticalOrderIterator : Iterator
{
private WordsCollection _collection;
// Lưu trữ vị trí duyệt hiện tại. Một trình lặp có thể có nhiều trường
// khác để lưu trữ trạng thái lặp, đặc biệt khi nó được cho là
// hoạt động với một loại tập hợp cụ thể.
private int _position = -1;
private bool _reverse = false;
public AlphabeticalOrderIterator(WordsCollection collection, bool reverse = false)
{
this._collection = collection;
this._reverse = reverse;
if (reverse)
{
this._position = collection.getItems().Count;
}
}
public override object Current()
{
return this._collection.getItems()[_position];
}
public override int Key()
{
return this._position;
}
public override bool MoveNext()
{
int updatedPosition = this._position + (this._reverse ? -1 : 1);
if (updatedPosition >= 0 && updatedPosition < this._collection.getItems().Count)
{
this._position = updatedPosition;
return true;
}
else
{
return false;
}
}
public override void Reset()
{
this._position = this._reverse ? this._collection.getItems().Count - 1 : 0;
}
}
// Tập hợp cung cấp một hoặc một số phương thức để truy xuất
// các thể hiện trình lặp mới, tương thích với lớp tập hợp.
class WordsCollection : IteratorAggregate
{
List<string> _collection = new List<string>();
bool _direction = false;
public void ReverseDirection()
{
_direction = !_direction;
}
public List<string> getItems()
{
return _collection;
}
public void AddItem(string item)
{
this._collection.Add(item);
}
public override IEnumerator GetEnumerator()
{
return new AlphabeticalOrderIterator(this, _direction);
}
}
class Program
{
static void Main(string[] args)
{
// Mã client có thể biết hoặc không biết về các lớp trình lặp hoặc tập hợp cụ thể,
// đối với việc triển khai này, tập hợp là chung để bạn có thể sử dụng với int
// hoặc với lớp tùy chỉnh.
var collection = new WordsCollection();
collection.AddItem("First");
collection.AddItem("Second");
collection.AddItem("Third");
Console.WriteLine("Straight traversal:");
foreach (var element in collection)
{
Console.WriteLine(element);
}
Console.WriteLine("\nReverse traversal:");
collection.ReverseDirection();
foreach (var element in collection)
{
Console.WriteLine(element);
}
}
}
}
Kết quả
Straight traversal:
First
Second
Third
Reverse traversal:
Third
Second
First
Để lại một bình luận