模板模式
Template Method模式也叫模板方法模式,是行为模式之一,它把具有特定步骤算法中的某些必要的处理委让给抽象方法,通过子类继承对抽象方法的不同实现改变整个算法的行为。
Template Method模式一般应用在具有以下条件
的应用中:
- 具有统一的操作步骤或操作过程
- 具有不同的操作细节
- 存在多个具有同样操作步骤的应用场景,但某些具体的操作细节却各不相同
总结:在抽象类中统一操作步骤,并规定好接口;让子类实现接口。这样可以把各个具体的子类和操作步骤接耦合
#include "iostream"
using namespace std;
class MakeCar
{
public:
virtual void MakeHead()=0;
virtual void MakeBody()=0;
virtual void MakeTail()=0;
virtual void Make() //模板函数把业务逻辑给确定好了
{
MakeTail();
MakeBody();
MakeHead();
}
};
class Jeep: public MakeCar
{
public:
virtual void MakeHead()
{
cout<<"Jeep Head"<<endl;
}
virtual void MakeBody()
{
cout<<"Jeep Body"<<endl;
}
virtual void MakeTail()
{
cout<<"Jeep Tail"<<endl;
}
};
class Bus:public MakeCar
{
public:
virtual void MakeHead()
{
cout<<"Bus Head"<<endl;
}
virtual void MakeBody()
{
cout<<"Bus Body"<<endl;
}
virtual void MakeTail()
{
cout<<"Bus Tail"<<endl;
}
};
void main()
{
MakeCar* car = new Bus;
car->Make();
delete car;
system("pause");
return ;
}
命令模式
Command模式行为设计模式的一种。Command模式通过被称为Command的类封装了对目标对象的调用行为以及调用参数。
在面向对象的程序设计中,一个对象调用另一个对象,一般情况下的调用过程是:创建目标对象实例;设置调用参数;调用目标对象的方法。但在有些情况下有必要使用一个专门的类对这种调用过程加以封装,我们把这种专门的类称作command类。整个调用过程比较繁杂,或者存在多处这种调用。这时,使用Command类对该调用加以封装,便于功能的再利用。调用前后需要对调用参数进行某些处理。调用前后需要进行某些额外处理,比如日志,缓存,记录历史操作等。
角色和职责
Command类:Command命令的抽象类。
ConcreteCommand类:Command的具体实现类。
Receiver:需要被调用的目标对象。
Invorker:通过Invorker执行Command对象。
适用于:是将一个请求封装为一个对象,从而使你可用不同的请求对客户端进行参数化;对请求排队或记录请求日志,以及支持可撤销的操作。
#include "iostream"
using namespace std;
#include "list"
class Doctor
{
public:
void treat_eye()
{
cout<<"医生治疗眼科病"<<endl;
}
void treat_nose()
{
cout<<"医生治疗鼻科病"<<endl;
}
};
class Command
{
public:
virtual void treat()=0;
};
class CommandTreatEye:public Command
{
public:
CommandTreatEye(Doctor *doctor)
{
m_doctor = doctor;
}
void treat()
{
m_doctor->treat_eye();
}
private:
Doctor *m_doctor;
};
class CommandTreatNose:public Command
{
public:
CommandTreatNose(Doctor *doctor)
{
m_doctor = doctor;
}
void treat()
{
m_doctor->treat_nose();
}
private:
Doctor *m_doctor;
};
class BeautyNurse
{
public:
BeautyNurse()
{
m_list.clear();
}
void setCommand(Command *command)
{
m_list.push_back(command);
}
void SubmitCase()
{
for (list<Command*>::iterator it=m_list.begin();it!=m_list.end();it++)
{
(*it)->treat();
}
}
private:
Command *m_command;
list<Command *> m_list;
};
void main()
{
BeautyNurse *nurse = NULL;
Doctor *doctor = NULL;
Command *command1 = NULL;
Command *command2 = NULL;
doctor = new Doctor;
command1 = new CommandTreatEye(doctor);
command2 = new CommandTreatNose(doctor);//客户端面向命令进行编程
nurse = new BeautyNurse();
nurse->setCommand(command1);
nurse->setCommand(command2);
nurse->SubmitCase();
delete nurse;
delete doctor;
delete command1;
delete command2;
system("pause");
return ;
}
责任链模式
Chain of Responsibility(CoR)模式也叫职责链模式或者职责连锁模式,是行为模式之一,该模式构造一系列分别担当不同的职责的类的对象来共同完成一个任务,这些类的对象之间像链条一样紧密相连,所以被称作职责链模式。
角色和职责
Handler :处理类的抽象父类。
concreteHandler :具体的处理类。
优点:
1。责任的分担。每个类只需要处理自己该处理的工作(不该处理的传递给下一个对象完成),明确各类的责任范围,符合类的最小封装原则。
2。可以根据需要自由组合工作流程。如工作流程发生变化,可以通过重新分配对象链便可适应新的工作流程。
3。类与类之间可以以松耦合的形式加以组织。
缺点:
因为处理时以链的形式在对象间传递消息,根据实现方式不同,有可能会影响处理的速度。
适用于:链条式处理事情。工作流程化、消息处理流程化、事物流程化;
#include "iostream"
using namespace std;
class CarHandle
{
public:
virtual void HandleCar()=0;
CarHandle* setNextHandle(CarHandle* handle)//需要把任务传递下去
{
m_handle = handle;
return m_handle;
}
protected:
CarHandle *m_handle; //下一个处理单元
};
class HeadCarHandle:public CarHandle
{
public:
virtual void HandleCar()
{
cout<<"制造车头"<<endl;
if (m_handle!=NULL)
{
m_handle->HandleCar();
}
}
};
class BodyCarHandle:public CarHandle
{
public:
virtual void HandleCar()
{
cout<<"制造车身"<<endl;
if (m_handle!=NULL)
{
m_handle->HandleCar();
}
}
};
class TailCarHandle:public CarHandle
{
public:
virtual void HandleCar()
{
cout<<"制造车尾"<<endl;
if (m_handle!=NULL)
{
m_handle->HandleCar();
}
}
};
void main()
{
CarHandle *headhandle = new HeadCarHandle;
CarHandle *bodyhandle = new BodyCarHandle;
CarHandle *tailhandle = new TailCarHandle;
headhandle->setNextHandle(bodyhandle);
bodyhandle->setNextHandle(tailhandle);
tailhandle->setNextHandle(NULL);
headhandle->HandleCar();
delete headhandle;
delete tailhandle;
delete bodyhandle;
system("pause");
return ;
}
策略模式
Strategy模式也叫策略模式是行为模式之一,它对一系列的算法加以封装,为所有算法定义一个抽象的算法接口,并通过继承该抽象算法接口对所有的算法加以封装和实现,具体的算法选择交由客户端决定(策略)。Strategy模式主要用来平滑地处理算法的切换 。
角色和责任
Strategy:策略(算法)抽象。
ConcreteStrategy:各种策略(算法)的具体实现。
Context:策略的外部封装类,或者说策略的容器类。根据不同策略执行不同的行为。策略由外部环境决定。
适用于:准备一组算法,并将每一个算法封装起来,使得它们可以互换。
策略模式优缺点
它的优点有:
1. 策略模式提供了管理相关的算法族的办法。策略类的等级结构定义了一个算法或行为族。恰当使用继承可以把公共的代码移到父类里面,从而避免重复的代码。
2. 策略模式提供了可以替换继承关系的办法。继承可以处理多种算法或行为。如果不是用策略模式,那么使用算法或行为的环境类就可能会有一些子类,每一个子类提供一个不同的算法或行为。但是,这样一来算法或行为的使用者就和算法或行为本身混在一起。决定使用哪一种算法或采取哪一种行为的逻辑就和算法或行为的逻辑混合在一起,从而不可能再独立演化。继承使得动态改变算法或行为变得不可能。
3. 使用策略模式可以避免使用多重条件转移语句。多重转移语句不易维护,它把采取哪一种算法或采取哪一种行为的逻辑与算法或行为的逻辑混合在一起,统统列在一个多重转移语句里面,比使用继承的办法还要原始和落后。
策略模式的缺点有:
1. 客户端必须知道所有的策略类,并自行决定使用哪一个策略类。这就意味着客户端必须理解这些算法的区别,以便适时选择恰当的算法类。换言之,策略模式只适用于客户端知道所有的算法或行为的情况。
2. 策略模式造成很多的策略类。有时候可以通过把依赖于环境的状态保存到客户端里面,而将策略类设计成可共享的,这样策略类实例可以被不同客户端使用。换言之,可以使用享元模式来减少对象的数量。
#include "iostream"
using namespace std;
class Strategy
{
public:
virtual void crypt()=0;
};
class AES : public Strategy
{
public:
virtual void crypt()
{
cout<<"AES加密算法"<<endl;
}
};
class DES : public Strategy
{
public:
virtual void crypt()
{
cout<<"DES加密算法"<<endl;
}
};
class Context
{
public:
void setStrategy(Strategy *strategy)
{
this->strategy = strategy;
}
void myoperator()
{
strategy->crypt();
}
private:
Strategy *strategy;
};
void main()
{
Strategy *strategy = NULL;
strategy = new DES;
Context *cont = new Context;
cont->setStrategy(strategy);
cont->myoperator();
delete strategy;
delete cont;
system("pause");
return ;
}
中介者模式
Mediator模式也叫中介者模式,是由GoF提出的23种软件设计模式的一种。Mediator模式是行为模式之一,在Mediator模式中,类之间的交互行为被统一放在Mediator的对象中,对象通过Mediator对象同其他对象交互,Mediator对象起着控制器的作用。
GOOD:用一个中介对象来封装一系列的对象交互,中介者使各对象不需要显示的相互引用,从而降低耦合;而且可以独立地改变它们之间的交互。
角色和责任
Mediator抽象中介者:中介者类的抽象父类。
concreteMediator:具体的中介者类。
Colleague:关联类的抽象父类。
concreteColleague:具体的关联类。
适用于:用一个中介对象,封装一些列对象(同事)的交换,中介者是各个对象不需要显示的相互作用,从而实现了耦合松散,而且可以独立的改变他们之间的交换。
#include "iostream"
using namespace std;
#include "string"
class Mediator;
class Person
{
public:
Person(string name,int sex,int conid,Mediator *m)
{
m_name= name;
m_sex = sex;
m_conid = conid;
mediator = m;
}
string getName()
{
return m_name;
}
int getSex()
{
return m_sex;
}
int getConid()
{
return m_conid;
}
virtual void getParter(Person *p) = 0;
protected:
string m_name;
int m_sex;
int m_conid;
Mediator *mediator;
};
class Mediator
{
public:
void setMan(Person *man)
{
pMan = man;
}
void setWoman(Person *woman)
{
pWoman = woman;
}
virtual void getParter()
{
if (pWoman->getSex()==pMan->getSex())
{
cout<<"我不是同性恋"<<endl;
}
if (pWoman->getConid()==pMan->getConid())
{
cout<<pWoman->getName()<<"和"<<pMan->getName()<<"绝配"<<endl;
}else
{
cout<<pWoman->getName()<<"和"<<pMan->getName()<<"不配"<<endl;
}
}
protected:
Person *pMan;
Person *pWoman;
};
class Woman :public Person
{
public:
Woman(string name,int sex,int conid,Mediator *m):Person(name,sex,conid,m)
{
}
virtual void getParter(Person *p)
{
mediator->setMan(p);
mediator->setWoman(this);
mediator->getParter();
}
};
class Man :public Person
{
public:
Man(string name,int sex,int conid,Mediator *m):Person(name,sex,conid,m)
{
}
virtual void getParter(Person *p)
{
mediator->setMan(this);
mediator->setWoman(p);
mediator->getParter();
}
};
void main()
{
Mediator *m = new Mediator;
Person *Nina = new Woman("妮娜",2,5,m);
Person *Mike = new Man("迈克",1,4,m);
Person *Joey = new Man("乔伊",1,5,m);
Nina->getParter(Mike);
Nina->getParter(Joey);
system("pause");
return ;
}
观察者模式
Observer模式是行为模式之一,它的作用是当一个对象的状态发生变化时,能够自动通知其他关联对象,自动刷新对象状态。
Observer模式提供给关联对象一种同步通信的手段,使某个对象与依赖它的其他对象之间保持状态同步。
角色和责任
Subject(被观察者):被观察的对象。当需要被观察的状态发生变化时,需要通知队列中所有观察者对象。Subject需要维持(添加,删除,通知)一个观察者对象的队列列表。
ConcreteSubject:被观察者的具体实现。包含一些基本的属性状态及其他操作。
Observer(观察者):接口或抽象类。当Subject的状态发生变化时,Observer对象将通过一个callback函数得到通知。
ConcreteObserver:观察者的具体实现。得到通知后将完成一些具体的业务逻辑处理。
适用于:定义对象间一种一对多的依赖关系,使得每一个对象改变状态,则所有依赖于他们的对象都会得到通知。
#include "iostream"
#include "string"
#include "list"
using namespace std;
class Secretary;
class Player
{
public:
Player(Secretary *secretary)
{
this->m_secretary = secretary;
}
void update(string action)
{
cout<<"action:"<<action<<endl;
}
private:
Secretary *m_secretary;
};
class Secretary
{
public:
Secretary()
{
m_list.clear();
}
void Notify(string info)
{
for (list<Player *>::iterator it = m_list.begin();it!=m_list.end();it++)
{
(*it)->update(info);
}
}
void setPlayer(Player *o)
{
m_list.push_back(o);
}
private:
list<Player *> m_list;
};
void main()
{
Secretary *s1 = NULL;
Player *p1 = NULL;
Player *p2 = NULL;
s1 = new Secretary;
p1 = new Player(s1);
p2 = new Player(s1);
s1->setPlayer(p1);
s1->setPlayer(p2);
s1->Notify("老板来了");
s1->Notify("老板走了");
cout<<"hello..."<<endl;
system("pause");
return ;
}
备忘录模式
Memento模式也叫备忘录模式,是行为模式之一,它的作用是保存对象的内部状态,并在需要的时候(undo/rollback)恢复对象以前的状态。
角色和职责
Originator(原生者): 需要被保存状态以便恢复的那个对象。
Memento(备忘录): 该对象由Originator创建,主要用来保存Originator的内部状态。
Caretaker(管理者): 负责在适当的时间保存/恢复Originator对象的状态。
适用于:在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,这样就可以将以后的对象状态恢复到先前保存的状态。
适用于功能比较复杂的,但需要记录或维护属性历史的类;或者需要保存的属性只是众多属性中的一小部分时Originator可以根据保存的Memo还原到前一状态。
#include "iostream"
using namespace std;
#include "string"
class MememTo
{
public:
MememTo(string name,int age)
{
m_name = name;
m_age= age;
}
string getName()
{
return m_name;
}
int getAge()
{
return m_age;
}
void setName(string name)
{
this->m_name = name;
}
void setAge(int age)
{
this->m_age = age;
}
private:
string m_name;
int m_age;
};
class Person
{
public:
Person(string name,int age)
{
m_name = name;
m_age= age;
}
string getName()
{
return m_name;
}
int getAge()
{
return m_age;
}
void setName(string name)
{
this->m_name = name;
}
void setAge(int age)
{
this->m_age = age;
}
MememTo* creatMemTo()
{
return new MememTo(m_name,m_age);
}
void setMememTo(MememTo* memto)
{
this->m_age = memto->getAge();
this->m_name = memto->getName();
}
void printP()
{
cout<<"m_name:"<<m_name<<"\t"<<"m_age:"<<m_age<<endl;
}
private:
string m_name;
int m_age;
};
class Caretaker
{
public:
Caretaker(MememTo *memto)
{
this->memto = memto;
}
MememTo *getMememTo()
{
return memto;
}
void setMememTo(MememTo *memto)
{
this->memto = memto;
}
private:
MememTo *memto;
};
void main()
{
MememTo *memto = NULL;
Caretaker *taker = NULL;
Person *p = new Person("Nina",23);
p->printP();
taker = new Caretaker(p->creatMemTo());
memto = p->creatMemTo();
p->setAge(32);
p->printP();
taker->setMememTo(memto);
p->printP();
delete memto;
delete p;
cout<<"hello..."<<endl;
system("pause");
return ;
}
访问者模式
Visitor模式也叫访问者模式,是行为模式之一,它分离对象的数据和行为,使用Visitor模式,可以不修改已有类的情况下,增加新的操作角色和职责。
角色和职责
抽象访问者(Visitor)角色:声明了一个或者多个访问操作,形成所有的具体元素角色必须实现的接口。
具体访问者(ConcreteVisitor)角色:实现抽象访问者角色所声明的接口,也就是抽象访问者所声明的各个访问操作。
抽象节点(Element)角色:声明一个接受操作,接受一个访问者对象作为一个参量。
具体节点(ConcreteElement)角色:实现了抽象元素所规定的接受操作。
结构对象(ObiectStructure)角色:有如下的一些责任,可以遍历结构中的所有元素;如果需要,提供一个高层次的接口让访问者对象可以访问每一个元素;如果需要,可以设计成一个复合对象或者一个聚集,如列(List)或集合(Set)。
适用于:把数据结构 和 作用于数据结构上的操作 进行解耦合;
适用于数据结构比较稳定的场合
访问者模式总结:访问者模式优点是增加新的操作很容易,因为增加新的操作就意味着增加一个新的访问者。访问者模式将有关的行为集中到一个访问者对象中。
那访问者模式的缺点是是增加新的数据结构变得困难了
优缺点
访问者模式有如下的优点:
1,访问者模式使得增加新的操作变得很容易。如果一些操作依赖于一个复杂的结构对象的话,那么一般而言,增加新的操作会很复杂。而使用访问者模式,增加新的操作就意味着增加一个新的访问者类,因此,变得很容易。
2,访问者模式将有关的行为集中到一个访问者对象中,而不是分散到一个个的节点类中。
3,访问者模式可以跨过几个类的等级结构访问属于不同的等级结构的成员类。迭代子只能访问属于同一个类型等级结构的成员对象,而不能访问属于不同等级结构的对象。访问者模式可以做到这一点。
4,积累状态。每一个单独的访问者对象都集中了相关的行为,从而也就可以在访问的过程中将执行操作的状态积累在自己内部,而不是分散到很多的节点对象中。这是有益于系统维护的优点。
访问者模式有如下的缺点:
1,增加新的节点类变得很困难。每增加一个新的节点都意味着要在抽象访问者角色中增加一个新的抽象操作,并在每一个具体访问者类中增加相应的具体操作。
2,破坏封装。访问者模式要求访问者对象访问并调用每一个节点对象的操作,这隐含了一个对所有节点对象的要求:它们必须暴露一些自己的操作和内部状态。不然,访问者的访问就变得没有意义。由于访问者对象自己会积累访问操作所需的状态,从而使这些状态不再存储在节点对象中,这也是破坏封装的。
#include "iostream"
using namespace std;
#include "list"
class ParkElement;
class Visitor
{
public:
virtual void visit(ParkElement *parkelement) = 0;
};
class ParkElement
{
public:
virtual void accept(Visitor *visit) = 0;
};
class Park:public ParkElement
{
public:
Park()
{
m_list.clear();
}
void setParkElement(ParkElement *pe)
{
m_list.push_back(pe);
}
virtual void accept(Visitor *v)
{
for (list<ParkElement *>::iterator it = m_list.begin();it!=m_list.end();it++)
{
(*it)->accept(v);
}
}
private:
list<ParkElement *> m_list;
};
class ParkA:public ParkElement
{
public:
virtual void accept(Visitor *v)
{
v->visit(this);
}
};
class ParkB:public ParkElement
{
public:
virtual void accept(Visitor *v)
{
v->visit(this);
}
};
class VisitorA: public Visitor
{
public:
virtual void visit(ParkElement *parkelement)
{
cout<<"清洁工A完成公园A部分的打扫"<<endl;
}
};
class VisitorB:public Visitor
{
public:
virtual void visit(ParkElement *parkelement)
{
cout<<"清洁工B完成公园B部分的打扫"<<endl;
}
};
class ManagerVisitor: public Visitor
{
public:
virtual void visit(ParkElement *parkelement)
{
cout<<"管理者来视察公园"<<endl;
}
};
void main()
{
Visitor *vManager = new ManagerVisitor;
Park *park = new Park;
ParkElement *parkA = new ParkA;
ParkElement *parkB = new ParkB;
park->setParkElement(parkA);
park->setParkElement(parkB);
//整个公园 接受 管理者访问
park->accept(vManager);
delete parkA;
delete parkB;
delete park;
delete vManager;
system("pause");
return ;
}
状态模式
State模式也叫状态模式,是行为设计模式的一种。State模式允许通过改变对象的内部状态而改变对象的行为,这个对象表现得就好像修改了它的类一样。
状态模式主要解决的是当控制一个对象状态转换的条件表达式过于复杂时的情况。把状态的判断逻辑转译到表现不同状态的一系列类当中,可以把复杂的判断逻辑简化。
角色和职责
Context:用户对象。拥有一个State类型的成员,以标识对象的当前状态;
State:接口或基类。封装与Context的特定状态相关的行为;
ConcreteState:接口实现类或子类。实现了一个与Context某个状态相关的行为。
适用于:对象的行为,依赖于它所处的当前状态。行为随状态改变而改变的场景。
适用于:通过用户的状态来改变对象的行为。
#include <iostream>
using namespace std;
class Worker;
class State
{
public:
virtual void doSomeThing(Worker *w) = 0;
};
class Worker
{
public:
Worker();
int getHour()
{
return m_hour;
}
void setHour(int hour)
{
m_hour = hour;
}
State* getCurrentState()
{
return m_currstate;
}
void setCurrentState(State* state)
{
m_currstate = state;
}
void doSomeThing() //
{
m_currstate->doSomeThing(this);
}
private:
int m_hour;
State *m_currstate; //对象的当前状态
};
class State1 : public State
{
public:
void doSomeThing(Worker *w);
};
class State2 : public State
{
public:
void doSomeThing(Worker *w);
};
void State1::doSomeThing(Worker *w)
{
if (w->getHour() == 7 || w->getHour()==8)
{
cout << "吃早饭" << endl;
}
else
{
delete w->getCurrentState(); //状态1 不满足 要转到状态2
w->setCurrentState(new State2 );
w->getCurrentState()->doSomeThing(w); //
}
}
void State2::doSomeThing(Worker *w)
{
if (w->getHour() == 9 || w->getHour()==10)
{
cout << "工作" << endl;
}
else
{
delete w->getCurrentState(); //状态2 不满足 要转到状态3 后者恢复到初始化状态
w->setCurrentState(new State1); //恢复到当初状态
cout << "当前时间点:" << w->getHour() << "未知状态" << endl;
}
}
Worker::Worker()
{
m_currstate = new State1;
}
void main()
{
Worker *w1 = new Worker;
w1->setHour(8);
w1->doSomeThing();
w1->setHour(9);
w1->doSomeThing();
delete w1;
cout<<"hello..."<<endl;
system("pause");
return ;
}
解释模式
一些应用提供了内建(build-in)的脚本或宏语言来让客户可以定义他们能够在系统中进行的操作。Interpreter模式的目的就是使用一个解释器为用户提供一门定义语言的语法表示的解释器,然后通过这个解释器来解释语言的句子。
角色和职责
Context:解释器上下文环境类。用来存储解释器的上下文环境,比如需要解释的文法等。
AbstractExpression : 解释器抽象类。
ConcreteExpression:解释器具体实现类。
#include "iostream"
using namespace std;
class Context
{
public:
Context(int num)
{
m_num = num;
}
int getNum()
{
return m_num;
}
int getRes()
{
return m_res;
}
void setNum(int num)
{
m_num = num;
}
void setRes(int res)
{
m_res = res;
}
protected:
private:
int m_num;
int m_res;
};
class Expression
{
public:
Expression(Context *context)
{
m_context =context;
}
virtual void interpreter()=0;
private:
Context *m_context;
};
class PlusExpression:public Expression
{
public:
PlusExpression(Context *context):Expression(context)
{
m_context =context;
}
virtual void interpreter()
{
int num = m_context->getNum();
num++;
m_context->setNum(num);
m_context->setRes(num);
}
private:
Context *m_context;
};
class MinusExpression:public Expression
{
public:
MinusExpression(Context *context):Expression(context)
{
m_context =context;
}
virtual void interpreter()
{
int num = m_context->getNum();
num--;
m_context->setNum(num);
m_context->setRes(num);
}
private:
Context *m_context;
};
void main()
{
Expression *expression1 = NULL;
Expression *expression2 = NULL;
Context *context = NULL;
context = new Context(10);
cout<<context->getNum()<<endl;
expression1 = new PlusExpression(context);
expression1->interpreter();
cout<<context->getNum()<<endl;
expression2 = new MinusExpression(context);
expression2->interpreter();
cout<<context->getNum()<<endl;
system("pause");
return ;
}
迭代器模式
Iterator模式也叫迭代模式,是行为模式之一,它把对容器中包含的内部对象的访问委让给外部类,使用Iterator(遍历)按顺序进行遍历访问的设计模式。
在应用Iterator模式之前,首先应该明白Iterator模式用来解决什么问题。或者说,如果不使用Iterator模式,会存在什么问题。
1.由容器自己实现顺序遍历。直接在容器类里直接添加顺序遍历方法
2.让调用者自己实现遍历。直接暴露数据细节给外部。
以上方法1与方法2都可以实现对遍历,这样有问题呢?
1,容器类承担了太多功能:一方面需要提供添加删除等本身应有的功能;一方面还需要提供遍历访问功能。
2,往往容器在实现遍历的过程中,需要保存遍历状态,当跟元素的添加删除等功能夹杂在一起,很容易引起混乱和程序运行错误等。
Iterator模式就是为了有效地处理按顺序进行遍历访问的一种设计模式,简单地说,Iterator模式提供一种有效的方法,可以屏蔽聚集对象集合的容器类的实现细节,而能对容器内包含的对象元素按顺序进行有效的遍历访问。所以,Iterator模式的应用场景可以归纳为满足以下几个条件:
- 访问容器中包含的内部对象
- 按顺序访问
GOOD:提供一种方法顺序访问一个聚敛对象的各个元素,而又不暴露该对象的内部表示。
为遍历不同的聚集结构提供如开始,下一个,是否结束,当前一项等统一接口。
角色和职责
Iterator(迭代器接口):该接口必须定义实现迭代功能的最小定义方法集:比如提供hasNext()和next()方法。
ConcreteIterator(迭代器实现类):迭代器接口Iterator的实现类。可以根据具体情况加以实现。
Aggregate(容器接口):定义基本功能以及提供类似Iterator iterator()的方法。
concreteAggregate(容器实现类):容器接口的实现类。必须实现Iterator iterator()方法。
//在迭代器中 持有 一个集合的 引用;所以通过迭代器,就可以访问集合
#include "iostream"
using namespace std;
typedef int Object;
#define SIZE 5
class MyIterator //迭代器抽象层
{
public:
virtual void First()=0;
virtual void Next()=0;
virtual bool isDone()=0;
virtual Object CurrentItem()=0;
};
class Aggregate //抽象的集合
{
public:
virtual MyIterator *CreateIterator()=0;
virtual Object getItem(int index)=0;
virtual int getSize()=0;
};
class ContreteIterator :public MyIterator //具体的迭代器
{
public:
ContreteIterator(Aggregate *ag)
{
_ag=ag;
_current_index = 0;
}
virtual void First()
{
_current_index = 0; //当前游标回到位置0
}
virtual void Next()
{
if (_current_index<_ag->getSize())
{
_current_index++;
}
}
virtual bool isDone()
{
return (_current_index==_ag->getSize());
}
virtual Object CurrentItem()
{
return _ag->getItem(_current_index);
}
private:
int _current_index;
Aggregate *_ag;
};
class ContreteAggregate : public Aggregate//具体的集合
{
public:
ContreteAggregate()
{
for (int i=0; i<SIZE; i++)
{
object[i] = i+1;
}
}
virtual MyIterator *CreateIterator()
{
return new ContreteIterator(this); //让迭代器持有一个集合的引用
}
virtual Object getItem(int index)
{
return object[index];
}
virtual int getSize()
{
return SIZE;
}
private:
Object object[SIZE];
};
void main()
{
Aggregate *ag = new ContreteAggregate();// 创建一个集合
MyIterator *it = ag->CreateIterator();// 创建一个遍历这个集合的 迭代器
for (; !(it->isDone()); it->Next() )//通过迭代器 遍历 集合
{
cout << it->CurrentItem() << " ";
}
delete it; //清理相关资源
delete ag;
system("pause");
return ;
}
----传智播客视频笔记及代码