?!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
View Code
再回头看看,自己写的代码都有点不认识了。是的,那个时候,是直接链表的创徏和遍历都攑֜一cMQ就是ؓ了方便,直到那天看了q代器设计模式,让我有了一ơ回q头来重新审视自己写q的代码Q认识自q不的机会?/span>
q代器模?/span>
在GOF的《设计模?可复用面向对象Y件的基础》一书中对P代器模式是这栯的:提供一U方法顺序访问一个聚合对象中各个元素Q而又不需要暴露该对象的内部表C?/span>
一个聚合对象,是所谓的对象容器了;作ؓ一个容器,都应该提供一U方法来让别人可以访问它的元素;但是Q有的时候,我是不希望遍历容器的人知道我的容器是如何实现的;那该怎么办?像我在大学那样实现的链表,只提供了从头到尾的遍历,如果我需要从ֈ头的遍历呢?是不是我又要d对应的方法了呢!Q!容器的遍历方式千变万化,我们不知道需求是如何的,如果需求变了,那么我们的代码就会发生很大的改动Q所以,我们需要去改变Q对于上面的代码Q当我对同一个链表对象进行多ơ遍历时Q是不是出Cm_pCurrent对象混ؕ的局面呢Q是的,q一切的一切,都说明,我们必须d一个容器的内部l构与它的遍历进行解耦,要是出现上面的情冉|Q我们就无法面对。就好比STL中的容器Q它容器中对象的实现和遍历很好的解耦了Q所以,我们无法知道它的内部是如何l织对象数据的,同时Q我们也可以按照我们自己的想法去遍历容器Q而不会出CQ何差错。在我们的项目中使用q代器模式就能很好的容器对象的内部表示与对它的遍历q行解耦。接下来Q我们再来详l的ȝq代器模式?/span>
UMLcd
IteratorQ定义P代器讉K和遍历元素的接口Q?/span>
ConcreteIteratorQ实现具体的q代器;
AggregateQ定义的容器Q创建相应P代器对象的接口;
ConcreteAggregateQ具体的容器实现创徏相应q代器的接口Q该操作q回ConcreteIterator的一个适当的实例?/span>
使用场合
讉K一个聚合对象的内容而无需暴露它的内部表示Q?/span>
支持对聚合对象的多种遍历Q从前到后,从后到前Q;
为遍历不同的聚合l构提供一个统一的接口,x持多态P代?/span>
作用
它支持以不同的方式遍历一个聚合,甚至都可以自己定义P代器的子cM支持新的遍历Q?/span>
q代器简化了聚合的接口,有了q代器的遍历接口Q聚合本w就不再需要类似的遍历接口了。这样就化了聚合的接口;
在同一个聚合上可以有多个遍历,每个q代器保持它自己的遍历状态;因此Q我们可以同时进行多个遍历?/span>
代码实现
View Code
代码中实C一个单向链表,链表与q代器解耦。对于多态P代,d抽象cAbstractJTListQ声明如下:
View Code
cJTListl承该抽象类Qƈ实现GetIteratorQ如下:
View Code
好了Q这L话,在客L׃用去new JTListIterator了,只需要这P
1 Iterator *pIterator = pJTList->GetIterator();
q就完全好了Q但是,q样又出现另外一个问题,我在GetIterator中new了一个JTListIteratorQ对于客L来说Q我q不知道q个new操作的存在,׃出现客户端不会去释放q个new开辟的内存Q那么如何实现这个内存的自动释放呢。好了,q合P代器模式Q再之前ȝ的RAII机制再实际运用一ơ?/span>
ҎRAII机制Q需要将q个q代器进行封装,让它h自动释放的功能,得借助另一个类Q如下:
复制代码
1 class IteratorPtr
2 {
3 public:
4 IteratorPtr(Iterator *pIterator) : m_pIterator(pIterator){}
5 ~IteratorPtr() { delete m_pIterator; }
6
7 Iterator *operator->(){ return m_pIterator; }
8 Iterator &operator*() { return *m_pIterator; }
9
10 private:
11 IteratorPtr(const IteratorPtr &);
12 IteratorPtr &operator=(const IteratorPtr &);
13 void *operator new(size_t size);
14 void operator delete(void *);
15
16 private:
17 Iterator *m_pIterator;
18 };
复制代码
我们在用的时候,像下面q样Q?/span>
1 IteratorPtr pIterator(pJTList->GetIterator());
q样qM释放q代器的ȝ了。这里一共涉及了三个DEMO工程Q提供完整DEMO工程下蝲。(工程下蝲Q?/span>
ȝ
q代器模式是一个很l典的模式。但是,是因ؓ它太l典了,如果每次都要E序员去重复造轮子,有点说不过MQ所以,现在基本成型的类库,都非常好的实Cq代器模式,在用这些类库提供的容器Ӟq不需要我们亲自去实现对应的P代器Q就好比STL了。但是话又说回来了,如此l典的东西,你不d习是不是很可惜啊Q是吧,在当今社会,技多不压n。好了,永远CQ设计模式是一U思想Qƈ不是一层不变的Q一U思想Q你懂的?/span>