迭代器和组合模式

来源:互联网 发布:数据库测试用例怎么写 编辑:程序博客网 时间:2024/04/30 11:29

迭代器:

当一个类A要将两个类B,C包含的内容整合到一起,而这两个类的内容使用不同的数据结构时,例如一个是数组,一个是List<>时。

解决方法就是将分别将B,C中的内容提取出来到一个新的结构中,如果这个事情由A来做:

A需要知道B,C内部的具体实现,代码如下:

    class C
    {
        C()
        {
            for (int i = 0; i < array.Length; i++)
            {
                array[i] = i;
            }
        }

        private int[] array = new int[10];
        public int[] Array
        {
            get
            {
                return array;
            }
        }
    }

    class B
    {
        B()
        {
            array = new List<int>();
            array.Add(0);
            array.Add(1);
            array.Add(2);
            array.Add(3);
        }

        private List<int> array;
        public List<int> Array
        {
            get
            {
                return array;
            }
        }

    }

    class A
    {
        private B _b;
        private C _c;

        A(B b, C c)
        {
            _b = b;
            _c = c;
        }

        private void print()
        {
            if (_b.Array != null && _b.Array.Count > 0)
            {
                //遍历_b.Array
            }

            if (_c.Array != null && _c.Array.Length > 0)
            {
                //遍历_c.Array
            }
        }
    }

 

这么做的坏处有:

1.我们针对B和C的具体编程,没有针对抽象编程。

2.A需要知道B和C的具体实现,违反了封装原则

3.增加或删除一种数据,将会变更A中的很多代码

4.如果改变B或C的数据存储方式,例如从List变为Dictionary,将使A中的代码进行大量不必要的修改。

 

改善思路:

B和C对自身的数据存储方式更为了解,所以由他们自身将数据存储方式转为一个共通的方式更合适,这样首先不用对外暴露内部实现。这个共通的存储方式我们可以自己实现,我们称之为迭代器,所以该模式也被命名为迭代器模式。另外,有些框架的数据结构例如Java的ArrayList以及其他数据结构都有自己的迭代器,使用起来十分方便。.Net中有iterator关键字,目前我不知道怎么用。


    interface IIterator
    {
        //for general struct
    }

    class IteratorForC : IIterator
    {
        //实现int[]想IIterator转换的算法和接口
    }

    class IteratorForB : IIterator
    {
        //实现List<>想IIterator转换的算法和接口
    }
   
    interface Base
    {
        IIterator CreateIterator();
    }
   

    class C : Base
    {
        C()
        {
            for (int i = 0; i < array.Length; i++)
            {
                array[i] = i;
            }
        }

        private int[] array = new int[10];
        public int[] Array
        {
            get
            {
                return array;
            }
        }

        public IIterator CreateIterator()
        {
            return new IteratorForC(); //return a change from int[] to IIterator
        }
    }

    class B:Base
    {
        B()
        {
            array = new List<int>();
            array.Add(0);
            array.Add(1);
            array.Add(2);
            array.Add(3);
        }
               
        private List<int> array;
        public List<int> Array
        {
            get
            {
                return array;
            }
        }

        public IIterator CreateIterator()
        {
            return new IteratorForB(); //return a change from int[] to IIterator
        }
    }

    class A
    {
        private Base _b;
        private Base _c;

        A(B b, C c)
        {
            _b = b;
            _c = c;
        }

        private void print()
        {
            IIterator iteratorb = _b.CreateIterator();
            IIterator iteratorc = _c.CreateIterator();

            //使用相同的算法遍历
        }
    }

 

这么做的好处:

1.A针对B和C的接口编程

2.将A和B,C解耦,A无需知道B和C的具体实现

3.增加和删除一个结构的数据对A影响范围比较小,这个地方还可以进一步改进。

4.当B或C的数据存储方式变化时,只需要修改对应的实现IIterator的类就可以了,不会影响到A。

 

组合模式日后再写下来,今天太累了。