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

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

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

抽象迭代器(Iterator):定义了遍历聚合对象所需的方法,包括hashNext()和next()方法等,用于遍历聚合对象中的元素。

具体迭代器(Concrete Iterator):它是实现迭代器接口的具体实现类,负责具体的遍历逻辑。它保存了当前遍历的位置信息,并可以根据需要向前或向后遍历集合元素。

抽象聚合器(Aggregate): 一般是一个接口,提供一个iterator()方法,例如java中的Collection接口,List接口,Set接口等。

具体聚合器(ConcreteAggregate):就是抽象容器的具体实现类,比如List接口的有序列表实现ArrayList,List接口的链表实现LinkList,Set接口的哈希列表的实现HashSet等。

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

下面使用两个例子来说明

1.抽象的例子

(一)Aggregate

抽象聚合器

csharp 复制代码
    abstract class Aggregate
    {
        public abstract Iterator CreateIterator();
    }

(二)ConcreteAggregate

具体聚合器

csharp 复制代码
    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

抽象迭代器

csharp 复制代码
    abstract class Iterator
    {
        public abstract object First();
        public abstract object Next();
        public abstract bool IsDone();
        public abstract object CurrentItem();
    }

(四)ConcreteIterator

具体迭代器

csharp 复制代码
    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;
        }
    }

(五)测试

csharp 复制代码
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

歌曲信息

csharp 复制代码
    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

抽象迭代器

csharp 复制代码
    public interface SongIterator
    {
        IEnumerator GetIterator();
    }

(三)SongsOfThe70s

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

csharp 复制代码
    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年代歌曲,既是迭代器又是聚合器

csharp 复制代码
    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;
        }
    }

(五)测试

csharp 复制代码
    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());
        }
    }
相关推荐
哆啦A梦的口袋呀1 小时前
基于Python学习《Head First设计模式》第十一章 代理模式
学习·设计模式·代理模式
9765033352 小时前
iOS 审核 cocos 4.3a【苹果机审的“分层阈值”设计】
flutter·游戏·unity·ios
Dave_Young2 小时前
上位机开发中的设计模式(3):装饰器模式
设计模式·装饰器模式
缘友一世4 小时前
java设计模式[2]之创建型模式
java·开发语言·设计模式
秋田君13 小时前
深入理解JavaScript设计模式之策略模式
javascript·设计模式·策略模式
EQ-雪梨蛋花汤15 小时前
【Unity笔记】Unity Animation组件使用详解:Play方法重载与动画播放控制
笔记·unity·游戏引擎
不会编程的小江江15 小时前
【设计模式】UML类图与工厂模式
c++·设计模式
lpfasd12316 小时前
备忘录模式(Memento Pattern)
java·设计模式·备忘录模式
AgilityBaby16 小时前
Untiy打包安卓踩坑
android·笔记·学习·unity·游戏引擎
lpfasd12317 小时前
模板方法模式(Template Method Pattern)
java·开发语言·设计模式·模板方法模式