[設計模式練習]迭代器模式

[設計模式練習]迭代器模式

將星期數(一到日)用迭代器設計

類別圖

Iterator

物件檔定義

using System.Collections.Generic;
using System.Collections;
using System.Text;

namespace DesignModelTest.迭代器
{
    #region 使用gof的迭代器
    /// <summary>
    /// 迭代器
    /// </summary>
    abstract class Iterator
    {
        public abstract object First();//第一筆資料
        public abstract object Next();//下一筆資料
        public abstract bool IsDone();//是否到資料尾端
        public abstract object CurrentItem();//顯示目前物件

    }
    /// <summary>
    /// 聚集抽象類別:星期數
    /// </summary>
    abstract class WeekDays
    {
        public abstract Iterator CreateIterator();
    }

    /// <summary>
    /// 聚集具體類別:星期數
    /// </summary>
    class ConcreteWeekDays : WeekDays
    {
        private IList<object> items = new List<object>();
        public override Iterator  CreateIterator()
        {
            return new ConcreteIterator(this);
        }
        public int Count
        {
            get { return items.Count; }
        }
        public object this[int index]
        {
            get { return items[index];}
            set { items.Insert(index, value); }
        }
    }
    /// <summary>
    /// 實現迭代器 : 正向
    /// </summary>
    class ConcreteIterator : Iterator
    {
        private ConcreteWeekDays weekdays;
        private int current = 0;//聚集物件的索引
        public ConcreteIterator(ConcreteWeekDays weekdays)
        {
            this.weekdays = weekdays;
        }
        public override object First()
        {
            return weekdays[0];
        }
        public override object Next()
        {
            object ret = null;
            current ++;
            if(current < weekdays.Count )
            {
                ret = weekdays[current];
            }
            return ret;
        }
        public override bool IsDone()
        {
            return current >= weekdays.Count ? true : false;
        }
        public override object CurrentItem()
        {
            return weekdays[current];
        }
    }
    /// <summary>
    /// 實現迭代器 : 反向
    /// </summary>
    class ConcreteIteratorDec : Iterator
    {
        private ConcreteWeekDays weekdays;
        private int current = 0;
        public ConcreteIteratorDec(ConcreteWeekDays weekdays)
        {
            this.weekdays = weekdays;
            current = weekdays.Count - 1;
        }
        public override object First()
        {
            return weekdays[weekdays.Count - 1];
        }
        public override object Next()
        {
            object ret = null;
            current--;
            if (current >=0)
            {
                ret = weekdays[current];
            }
            return ret;
        }
        public override bool IsDone()
        {
            return current < 0 ? true : false;
        }
        public override object CurrentItem()
        {
            return weekdays[current];
        }
    }
    #endregion
    #region IEnumerable 及 IEnumerator使用
    public class Person
    {
        public Person(string fName, string lName)
        {
            this.firstName = fName;
            this.lastName = lName;
        }

        public string firstName;
        public string lastName;
    }

    public class People : IEnumerable
    {
        private Person[] _people;
        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 new PeopleEnum(_people);
        }
    }

    public class PeopleEnum : IEnumerator
    {
        public Person[] _people;

        // Enumerators are positioned before the first element
        // until the first MoveNext() call.
        int position = -1;

        public PeopleEnum(Person[] list)
        {
            _people = list;
        }

        public bool MoveNext()
        {
            position++;
            return (position < _people.Length);
        }

        public void Reset()
        {
            position = -1;
        }

        public object Current
        {
            get
            {
                try
                {
                    return _people[position];
                }
                catch (IndexOutOfRangeException)
                {
                    throw new InvalidOperationException();
                }
            }
        }
    }
    #endregion

}

用戶端程式碼

            DesignModelTest.迭代器.ConcreteWeekDays weekdays = new DesignModelTest.迭代器.ConcreteWeekDays();
            //將物件加入陣列
            weekdays[0] = "星期一";
            weekdays[1] = "星期二";
            weekdays[2] = "星期三";
            //改變使用的迭代器計算邏輯也會改變
            DesignModelTest.迭代器.Iterator i = new DesignModelTest.迭代器.ConcreteIterator(weekdays);
            DesignModelTest.迭代器.Iterator idec = new DesignModelTest.迭代器.ConcreteIteratorDec(weekdays);
            object item = i.First();
            Console.WriteLine("正向排序");
            while (!i.IsDone())
            {
                Console.WriteLine(i.CurrentItem());
                i.Next();
            }
            Console.WriteLine("反向排序");
            while (!idec.IsDone())
            {
                Console.WriteLine(idec.CurrentItem());
                idec.Next();
            }
          
            /*使用IEnumerableI及Enumerator介面
             */
            DesignModelTest.迭代器.Person[] peopleArray = new DesignModelTest.迭代器.Person[3]
            {
                new DesignModelTest.迭代器.Person("John", "Smith"),
                new DesignModelTest.迭代器.Person("Jim", "Johnson"),
                new DesignModelTest.迭代器.Person("Sue", "Rabon"),
            };
            DesignModelTest.迭代器.People peopleList = new DesignModelTest.迭代器.People(peopleArray);
            foreach (DesignModelTest.迭代器.Person p in peopleList)
                Console.WriteLine(p.firstName + " " + p.lastName);
            Console.Read();
            #endregion

輸出結果

pic1