Unity实现设计模式——迭代器模式

Unity实现设计模式——迭代器模式

迭代器模式是一种行为型设计模式,它提供了一种统一的方式来访问集合对象中的元素,而不是暴露集合内部的表示方式。简单地说,就是将遍历集合的责任封装到一个单独的对象中,我们可以按照特定的方式访问集合中的元素。

抽象迭代器(Iterator):定义了遍历聚合对象所需的方法,包括hashNext()和next()方法等,用于遍历聚合对象中的元素。
具体迭代器(Concrete Iterator):它是实现迭代器接口的具体实现类,负责具体的遍历逻辑。它保存了当前遍历的位置信息,并可以根据需要向前或向后遍历集合元素。
抽象聚合器(Aggregate): 一般是一个接口,提供一个iterator()方法,例如java中的Collection接口,List接口,Set接口等。
具体聚合器(ConcreteAggregate):就是抽象容器的具体实现类,比如List接口的有序列表实现ArrayList,List接口的链表实现LinkList,Set接口的哈希列表的实现HashSet等。

简单来说就是容器的种类我们不需要知道是什么(List,HasSet等)我们只要获取到迭代器就可以进行遍历。
下面使用两个例子来说明

1.抽象的例子

(一)Aggregate

抽象聚合器

    abstract class Aggregate
    {
        public abstract Iterator CreateIterator();
    }

(二)ConcreteAggregate

具体聚合器

    class ConcreteAggregate : Aggregate
    {
        private ArrayList _items = new ArrayList();

        public override Iterator CreateIterator()
        {
            return new ConcreteIterator(this);
        }

        // Gets item count
        public int Count
        {
            get { return _items.Count; }
        }

        // Indexer
        public object this[int index]
        {
            get { return _items[index]; }
            set { _items.Insert(index, value); }
        }
    }

(三)Iterator

抽象迭代器

    abstract class Iterator
    {
        public abstract object First();
        public abstract object Next();
        public abstract bool IsDone();
        public abstract object CurrentItem();
    }

(四)ConcreteIterator

具体迭代器

    class ConcreteIterator : Iterator
    {
        private ConcreteAggregate _aggregate;
        private int _current = 0;

        // Constructor
        public ConcreteIterator(ConcreteAggregate aggregate)
        {
            this._aggregate = aggregate;
        }

        // Gets first iteration item
        public override object First()
        {
            return _aggregate[0];
        }

        // Gets next iteration item
        public override object Next()
        {
            object ret = null;
            if (_current < _aggregate.Count - 1)
            {
                ret = _aggregate[++_current];
            }

            return ret;
        }

        // Gets current iteration item
        public override object CurrentItem()
        {
            return _aggregate[_current];
        }

        // Gets whether iterations are complete
        public override bool IsDone()
        {
            return _current >= _aggregate.Count;
        }
    }

(五)测试

public class IteratorStructure : MonoBehaviour
{
	void Start ( )
	{
        ConcreteAggregate a = new ConcreteAggregate();
        a[0] = "Item A";
        a[1] = "Item B";
        a[2] = "Item C";
        a[3] = "Item D";

        // Create Iterator and provide aggregate
        Iterator i = a.CreateIterator();

        Debug.Log("Iterating over collection:");

        object item = i.First();
        while (item != null)
        {
            Debug.Log(item);
            item = i.Next();
        }
    }
}

2.现实例子

这里使用一个不同年代的歌曲集来进行演示

(一)SongInfo

歌曲信息

    public class SongInfo
    {
        public string songName { get; protected set; }

        public string bandName { get; protected set; }

        public int yearReleased { get; protected set; }

        public SongInfo(string songName, string bandName, int yearReleased)
        {
            this.songName = songName;
            this.bandName = bandName;
            this.yearReleased = yearReleased;
        }

        public string ToStringEx()
        {
            return this.songName + " - " + this.bandName + " : " + this.yearReleased.ToString();
        }
    }

(二)SongIterator

抽象迭代器

    public interface SongIterator
    {
        IEnumerator GetIterator();
    }

(三)SongsOfThe70s

70年代歌曲,既是迭代器又是聚合器

    public class SongsOfThe70s : SongIterator
    {
        // here it is a list
        protected List<SongInfo> bestSongs;

        public SongsOfThe70s()
        {
            bestSongs = new List<SongInfo>();
        }

        public void AddSong(string name, string artist, int year)
        {
            SongInfo song = new SongInfo(name, artist, year);
            bestSongs.Add(song);
        }

        //about yeild return :http://www.jb51.net/article/54810.htm
        // heart
        public IEnumerator GetIterator()
        {
            foreach (SongInfo song in bestSongs)
                yield return song;
            yield break;
        }
    }

(四)SongsOfThe80s

80年代歌曲,既是迭代器又是聚合器

    public class SongsOfThe80s : SongIterator
    {
        // here we have an array
        protected SongInfo[] bestSongs;

        public SongsOfThe80s()
        {
            bestSongs = new SongInfo[0];
        }

        public void AddSong(string name, string artist, int year)
        {
            SongInfo song = new SongInfo(name, artist, year);
            // just for the sake of easyness of appending something we will convert the array to a list
            List<SongInfo> newSongs = new List<SongInfo>(bestSongs);
            // add a new element
            newSongs.Add(song);
            // and convert it back to an array
            bestSongs = newSongs.ToArray();
        }

        // heart
        public IEnumerator GetIterator()
        {
            foreach (SongInfo song in bestSongs)
                yield return song;
            yield break;
        }
    }

(五)测试

    void Start()
    {
        // creating the collections and adding some songs:
        SongsOfThe70s song70s = new SongsOfThe70s();
        song70s.AddSong("song title", "song artist", 1974);
        song70s.AddSong("song title2", "song artist2", 1978);

        SongsOfThe80s song80s = new SongsOfThe80s();
        song80s.AddSong("song title 80s", "song artist 80s", 1985);
        song80s.AddSong("song title2 80s", "song artist2 80s", 1989);

        // because of the iterator pattern we can loop through both types
        // of collections the same simple way and don't have to bother
        // with what type of collection the object stores:

        IEnumerator songsOfThe70sIterator = song70s.GetIterator();
        while (songsOfThe70sIterator.MoveNext())
        {
            SongInfo info = (SongInfo)songsOfThe70sIterator.Current;
            Debug.Log("Song 70s: " + info.ToStringEx());
        }

        IEnumerator songsOfThe80sIterator = song80s.GetIterator();
        while (songsOfThe80sIterator.MoveNext())
        {
            SongInfo info = (SongInfo)songsOfThe80sIterator.Current;
            Debug.Log("Song 80s: " + info.ToStringEx());
        }
    }

你可能感兴趣的:(设计模式,unity,设计模式,迭代器模式)