Unity【话大】设计模式之迭代器模式

前言:笔者在最开始写程序的时候经常会遇到一种情况,例如更改一个字段、或者添加一种小功能,就要把原来写过的东西几乎废弃掉,或者更改大量以前写过的代码。又或者自己写的东西时间久了再去回顾,完全找不到到时为什么这么写的头绪,如果遇到了Bug更是无法快速定位在哪里小范围出现的问题。如果你也经常遇到这种问题,就说明你现阶段非常需要学习下设计模式了

在网上经常说的设计模式有23种,也有一些更多的设计模式,无非也是从这些设计模式中变种而来。如果让笔者来形容什么是设计模式,我认为设计模式是:一种思想,一种模式,一种套路,一种解决问题的高效策略



有说的不正确或者不准确的地方欢迎留言指正


有什么有趣的写作技巧或者想法欢迎大家给我留言,大家的帮助是我写下去最有效的动力



7643202-9c63a516f1d6c7ea.jpg

在日常开中我们一定用到过 foreach。 这种遍历方式可以在 Array IList IDictionary等数据结构中通用。其实他的实现其实就是用到的迭代器模式,今天笔者就跟大家说一说迭代器的实现方式。

迭代器模式(IteratorPattern) 提供一种方法顺序访问一个聚合对象中各个元素,而又不暴露该对象的内部表示。

下面笔者逐步完成迭代器模式的构建

首先我们先创建一个简单的集合

    public class Group
    {
        private IList<object> items = new List<object>();
        public int Count
        {
            get { return items.Count; }
        }
        public object this[int index]
        {
            get { return items[index]; }
            set { items.Insert(index, value); }
        }
    }

为了让多种集合都能使用同一种遍历方式,我们再创建一个通用迭代器

    public class Iterator
    {
        private IList<object> items = new List<object>();
        public Iterator(IList<object> tempItems)
        {
            items = tempItems;
        }
        private int index = -1;
        public object Current
        {
            get { return items[index]; }
        }
        public bool MoveNext()
        {
            return items.Count > ++index;
        }
        public void Reset()
        {
            index = -1;
        }
    }

然后我们把迭代器镶嵌到这个集合中

    public class Group
    {
        private IList<object> items = new List<object>();
        public int Count
        {
            get { return items.Count; }
        }
        public object this[int index]
        {
            get { return items[index]; }
            set { items.Insert(index, value); }
        }

        public Iterator GetIterator()
        {
            return new Iterator(items);
        }
    }
调用~这样我们一个简单的迭代器就完成了
    void Start()
    {
        Group group = new Group();
        group[0] = "爱";
        group[1] = "生";
        group[2] = "活";
        group[3] = "爱";
        group[4] = "海";
        group[5] = "澜";

        Iterator iterator = group.GetIterator();

        while (iterator.MoveNext())
        {
            this.Log($"现在的元素为:{iterator.Current}");
        }
    }
7643202-f0fdcda2cb568e76.png
是不是很简单呢?接下来我们开始重构

Iterator中我们不能确定这个遍历的集合是列表、字典还是数组,但是我们可以确定他们都含有CurrentMoveNextReset三种元素
所以我们将这三种元素进行抽象,与原来的迭代器类进行剥离

    public interface IteratorBase
    {
        object Current { get; }
        bool MoveNext();
        void Reset();
    }

原迭代器类继承接口IteratorBase

    public class Iterator: IteratorBase
    {
        private IList<object> items = new List<object>();
        public Iterator(IList<object> tempItems)
        {
            items = tempItems;
        }
        private int index = -1;
        public object Current
        {
            get { return items[index]; }
        }
        public bool MoveNext()
        {
            return items.Count > ++index;
        }
        public void Reset()
        {
            index = -1;
        }
    }

既然原迭代器类继承接口IteratorBase,那么以可以根据这个接口所规定的结构,让细节的实现统统转移到子类中实现,也就是说,我们可以定义出多种满足不同迭代需求的迭代类,但是调用的函数都是一样的,因为都继承自IteratorBase。根据里氏替换原则我们知道,对应的Group中所返回的public Iterator GetIterator()完全可以用接口IteratorBase代替

    public class Group
    {
        private IList<object> items = new List<object>();
        public int Count
        {
            get { return items.Count; }
        }
        public object this[int index]
        {
            get { return items[index]; }
            set { items.Insert(index, value); }
        }

        public IteratorBase GetIterator()
        {
            return new Iterator(items);
        }
    }

最后,为了区分什么样子的集合可以使用通用迭代模式,我们做一个获得迭代器的接口,只要继承这个接口的集合,就都可以使用通用迭代模式了

    public interface IEnumerable
    {
        IteratorBase GetIterator();
    }

    public class Group: IEnumerable
    {
        private IList<object> items = new List<object>();
        public int Count
        {
            get { return items.Count; }
        }
        public object this[int index]
        {
            get { return items[index]; }
            set { items.Insert(index, value); }
        }

        public IteratorBase GetIterator()
        {
            return new Iterator(items);
        }
    }

经过剥离和抽象,我们的迭代器模式就完成了。迭代器就是把原有需要遍历的结构进行一次包装,把包装后的结构再统一进行遍历

其实在C# 中自带的迭代器要比我们这个更强大,他最大的特点就是按需逐步查询 Unity 之数据集合解析中的最后IEnumerable补充部分有例子说明,这里就不在熬述。
所以说微软有更好的,就用微软的,这种无用的轮子我们还是不要浪费时间再造了,了解下原理就好。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值