迭代器:
当一个类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。
组合模式日后再写下来,今天太累了。