【设计模式学习笔记十七】【行为模式】【迭代器模式(Interpreter)】
2015-02-05 21:55
627 查看
本文是学习刘伟技术博客和《设计模式-可复用面向对象软件的基础》笔记,博客链接:/article/1610242.html
主要是对博客和书本做提炼和记录,更多是对设计模式的基础框架学习,细节将略去,侧重对每个设计模式框架的理解。
我应该理解和掌握的:
1)能够画出这个设计模式的架构框图;
2)能够根据架构框图写出对应的伪代码;
3)这个模式的应用场景,主要优缺点。
b) ConcreteIterator(具体迭代器):具体迭代器实现迭代器的接口,对该聚合遍历时跟踪当前位置;
c) Aggregate(聚合):存储和管理元素对象,声明一个createIterator()方法用于创建一个迭代器对象,充当抽象迭代器工厂的角色。
d) ConcreteAggregate(具体聚合类):创建相应迭代器的接口,该操作返回ConcreteIterator的一个适当的实例。
b) 迭代器简化了聚合类的接口。
c) 在同一个聚合器上可以有多个遍历。每个迭代器保持他自己的遍历状态,因此可以同时进行多个遍历。
d) 在迭代器中引入抽象层,增加新的聚合类和迭代器很方便,无需修改原有代码,符合开闭原则。
b) 抽象迭代器的设计难度较大,需要充分考虑到系统将来的扩展。
2) 支持对聚合对象的多种遍历。
3) 为遍历不同的聚合结构提供一个统一的接口。
主要是对博客和书本做提炼和记录,更多是对设计模式的基础框架学习,细节将略去,侧重对每个设计模式框架的理解。
我应该理解和掌握的:
1)能够画出这个设计模式的架构框图;
2)能够根据架构框图写出对应的伪代码;
3)这个模式的应用场景,主要优缺点。
1.迭代器模式
迭代器是很常见的模式,他将聚合类中负责遍历数据的方法提取出来,封装到专门的类中,实现数据存储和数据遍历的分离,无需暴露聚合类的内部类属性即可对其进行操作。我们常用聚合对象来存储一系列的数据,如vector,聚合对象拥有两个职责:一是存储数据,而是遍历数据。前者是聚合对象的基本职责,后者是可变化和分离的。将遍历数据的行为从聚合对象中分离出来,封装在一个被称为迭代器的对象中,由迭代器来提供遍历聚合类对象内部数据的行为。(1)定义
迭代器模式:提供一种方法顺序访问一个聚合对象中各个元素,而又不需要暴露该对象的内部元素。1)迭代器结构图
在迭代器结构图中包含聚合和迭代器两个层次结构,考虑到系统的灵活性和可扩展性,在迭代器中应用了工厂方法模式。2)参与者
a) Iterator(抽象迭代器):定义访问和遍历元素的借口;b) ConcreteIterator(具体迭代器):具体迭代器实现迭代器的接口,对该聚合遍历时跟踪当前位置;
c) Aggregate(聚合):存储和管理元素对象,声明一个createIterator()方法用于创建一个迭代器对象,充当抽象迭代器工厂的角色。
d) ConcreteAggregate(具体聚合类):创建相应迭代器的接口,该操作返回ConcreteIterator的一个适当的实例。
3)看图写代码
/* ** FileName : IteratorPattern ** Author : lin005 ** Date : 2015/02/08 ** Description : More information, please go to http://blog.csdn.net/amd123456789 */ //define a node typedef struct Node_s { int value; Node_s* next; }Node; class p_List; //提前申明 //Abstract Iterator class _Iterator { public: virtual ~_Iterator(){}; virtual void First() = 0; virtual void Next() = 0; virtual bool IsLast() = 0; virtual Node* getCurrentNode() = 0; }; //抽象迭代器的子类 class ConcreteIterator : public _Iterator { public: ConcreteIterator(p_List* l):list(l){} ~ConcreteIterator(); virtual void First(); //第一个元素 virtual void Next(); //当前元素的下一个元素 virtual bool IsLast(); //是否最后一个元素 virtual Node* getCurrentNode(); //获取当前迭代器所指向的元素 private: p_List* list; //包含链表 Node* pc; //当前元素 }; //链表 class p_List { public: p_List(){phead = NULL; ptail = NULL; count = 0;} ~p_List() { removeAll(); if(iter) { delete iter; iter = NULL; } } //获取元素个数 int getCount() { return count; } //获取指定元素 Node* get(const int a)const { Node* p = phead; while(p) { if(p->value == a) { return p; } p = p->next; } return NULL; } //获取第一个元素 Node* First()const { return phead; } //获取最后一个元素 Node* Last()const { return ptail; } //是否包含指定元素 bool IsInclude(const int a)const { Node* p = phead; while(p) { if(p->value == a) { return true; } p = p->next; } return false; } //添加一个指定元素 void add(const int a) { Node *pnew = new Node; pnew->next = NULL; pnew->value = a; if(phead == NULL) { phead = pnew; ptail = pnew; count++; } else { ptail->next = pnew; ptail = pnew; } } //删除一个元素 void remove(Node* p) { if(phead == NULL) return; if(phead == p) { if(phead->next == NULL) { ptail = NULL; } phead = p->next; delete p; p = NULL; } else { Node* pt = phead; while(pt) { if(pt->next == p) { //if(p->next == NULL) { // pt->next = NULL; } // else { pt->next = pt->next->next; } delete p; p = NULL; break; } pt = pt->next; } } } //删除所有元素 void removeAll() { while(phead) { Node* p = phead; phead = p->next; delete p; p = NULL; } ptail = NULL; } //是否第一个元素 bool isFirst(Node* p) { if(p == phead) return true; return false; } //链表是否为空 bool isEmpty() { return count == 0; } //生成一个迭代器 _Iterator* createdIter() { iter = new ConcreteIterator(this); return iter; } private: Node* phead; //第一个节点 Node* ptail; //最后一个节点 int count; //元素个数 _Iterator* iter; //迭代器 }; void ConcreteIterator::First() { pc = list->First(); } void ConcreteIterator::Next() { if(list->First()) { pc = pc->next; } else { pc = NULL; } } bool ConcreteIterator::IsLast() { return pc == list->Last()->next; } Node* ConcreteIterator::getCurrentNode() { return pc; } ConcreteIterator::~ConcreteIterator() { } //客户端测试 #define SAFE_DELETE(p) if(p){delete p; p = NULL;} int main(int argc, const char * argv[]) { p_List* l = new p_List(); l->add(20); l->add(30); l->add(40); _Iterator* iter = new ConcreteIterator(l);//有客户端主动生成迭代器,需要手动delete _Iterator* iter1 = l->createdIter(); //直接用链表自己生成 //客户端生成迭代器测试 for(iter->First(); !iter->IsLast();iter->Next()) { cout<<iter->getCurrentNode()->value<<endl; } //链表生成的迭代器 for(iter1->First(); !iter1->IsLast(); iter1->Next()) { if(iter1->getCurrentNode()->value == 20) { l->remove(iter1->getCurrentNode()); } } //链表生成迭代器测试 for(iter1->First(); !iter1->IsLast();iter1->Next()) { cout<<iter1->getCurrentNode()->value<<endl; } SAFE_DELETE(l); SAFE_DELETE(iter); return 0; }
(2)总结
1)优点
a) 支持不同的方式遍历一个聚合对象,在同一个聚合对象上可以定义多种遍历方式。仅需用一个不同的迭代器的实例替代原先的实例即可b) 迭代器简化了聚合类的接口。
c) 在同一个聚合器上可以有多个遍历。每个迭代器保持他自己的遍历状态,因此可以同时进行多个遍历。
d) 在迭代器中引入抽象层,增加新的聚合类和迭代器很方便,无需修改原有代码,符合开闭原则。
2)缺点
a) 迭代器分离了数据存储和遍历数据的职责,增加新的聚合类需要增加对应的迭代器类,类的个数成对增加,一定程度上增加的系统的复杂性。b) 抽象迭代器的设计难度较大,需要充分考虑到系统将来的扩展。
(3)适用场景
1) 访问一个聚合对象而无需暴露它的内部表示。2) 支持对聚合对象的多种遍历。
3) 为遍历不同的聚合结构提供一个统一的接口。
相关文章推荐
- 【设计模式学习笔记十六】【行为模式】【解释器模式(Interpreter)】
- 设计模式学习笔记(十七)——Command命令模式
- 设计模式学习笔记(十七)——Command命令模式
- 步步为营 .NET 设计模式学习笔记 二十三、Interpreter(解释器模式)
- 步步为营 .NET 设计模式学习笔记 十七、Flyweight(享元模式)
- HeadFirst 设计模式学习笔记7--迭代器模式
- 设计模式学习笔记(十七)——Command命令模式
- 设计模式C++学习笔记之十七(Chain of Responsibility责任链模式)
- 设计模式C++学习笔记之十四(Iterator迭代器模式)
- 设计模式学习笔记(十七)——Command命令模式
- 步步为营 .NET 设计模式学习笔记 十一、Iterator(迭代器模式)
- 设计模式学习笔记十七——Iterator模式
- 设计模式学习笔记(十七)——Interpreter解释器
- HeadFirst 设计模式学习笔记21-- 解释者(Interpreter)模式拾零
- 设计模式学习笔记之迭代器模式
- 设计模式学习笔记十七:组合模式(Composite Pattern)
- 步步为营 .NET 设计模式学习笔记 十一、Iterator(迭代器模式)
- HeadFirst 设计模式学习笔记9--迭代器模式
- 步步为营 .NET 设计模式学习笔记 二十三、Interpreter(解释器模式)
- 步步为营 .NET 设计模式学习笔记 二十三、Interpreter(解释器模式)