一、实验目的及要求
1、掌握行为型模式的概念。
2、掌握责任链模式、命令模式、解释器模式、迭代器模式、中介者模式的构造方式及使用情景。
二、实验设备(环境)
1、 软件需求: Dev-Cpp5.4, Rational Rose / Microsoft Visio
2、 硬件需求: Pentium III 450以上的CPU处理器,1G以上的内存,2G的*硬盘空间
三、实验内容
1、为了用户使用方便,遥控器提供了一个功能键,用户可以自定义功能键的功能,如功能键FunctionButton可以用于退出系统(SystemExitClass),也可以用于打开帮助界面(DisplayHelpClass)。现使用命令模式来设计该系统,使得功能键类与功能类之间解耦,相同的功能键可以对应不同的功能。
2、电视机遥控器就是一个迭代器的实例,通过它可以实现对电视机频道集合的遍历操作,本实例我们将模拟电视机遥控器的实现。请使用迭代器模式实现对于频道集合(100个频道)的2种遍历方式:(1)单步向前和单步向后遍历。(2)有条件的单步遍历。即在频道集合中屏蔽掉频道20-30和频道80-90(假设这些频道仅对VIP用户开放),也就是在单步遍历中跳过这些频道。
要求对于2种遍历(1)和(2)都要实现共同的接口setChannel(int i), currentChannel(), next(), previous(), isLast(), isFirst().
四、实验步骤与结果
练习一
1.命令模式设计结构图UML图:
2.实验运行结果截图:
3.代码分析
Command.h
#ifndef _COMMAND_H_
#define _COMMAND_H_
class Reciever;
class Command
{
public:
virtual ~Command();
virtual void Excute() = 0;
protected:
Command();
private:
};
class ConcreteCommand1:public Command
{
public:
ConcreteCommand1(Reciever* recv);
~ConcreteCommand1();
void Excute();
protected:
private:
Reciever* _recv;
};
class ConcreteCommand2:public Command
{
public:
ConcreteCommand2(Reciever* recv);
~ConcreteCommand2();
void Excute();
protected:
private:
Reciever* _recv;
};
#endif //~_COMMAND_H_
Command.cpp
#include "Command.h"
#include "Receiver.h"
#include<iostream>
using namespace std;
Command::Command()
{
}
Command::~Command()
{
}
ConcreteCommand1::ConcreteCommand1(Reciever * recv)
{
_recv = recv;
}
ConcreteCommand1::~ConcreteCommand1()
{
}
void ConcreteCommand1::Excute()
{
cout<<"1:退出系统"<<endl;
_recv->Action();
}
ConcreteCommand2::ConcreteCommand2(Reciever * recv)
{
_recv = recv;
}
ConcreteCommand2::~ConcreteCommand2()
{
}
void ConcreteCommand2::Excute()
{
cout<<"2:显示帮助页面"<<endl;
_recv->Action();
}
Invoker.h
#ifndef _INVOKER_H_
#define _INVOKER_H_
class Command;
class Invoker
{
public:
Invoker(Command* cmd);
~Invoker();
void Invoke();
void GetCommand(Command* cmd)
{
_cmd=cmd;
}
void SetCommand(Command* cmd)
{
_cmd=cmd;
}
protected:
private:
Command* _cmd;
};
#endif //~_INVOKER_H_
Invoker.cpp
#include "Invoker.h"
#include "Command.h"
Invoker::Invoker(Command * cmd)
{
_cmd = cmd;
}
Invoker::~Invoker()
{
}
void Invoker::Invoke()
{
_cmd->Excute();
}
Receiver.h
#ifndef _RECIEVER_H_
#define _RECIEVER_H_
class Reciever
{
public:
Reciever();
~Reciever();
void Action();
protected:
private:
};
#endif //~_RECIEVER_H_
Receiver.cpp
#include "Receiver.h"
#include <iostream>
Reciever::Reciever()
{
}
Reciever::~Reciever()
{
}
void Reciever::Action()
{
std::cout<<""<<std::endl;
}
main.cpp
/*
Reciever是接受者,电视机收到后做出action()的动作,显示
Invoker是遥控器,是控制者,发出Excute()的操作
两者被分隔开来
我们把命令封装起来,让两者 可以直接调用命令。
*/
#include "Command.h"
#include "Invoker.h"
#include "Receiver.h"
#include <iostream>
using namespace std;
int main(int argc,char* argv[])
{
cout<<"当前功能:"<<endl;
Reciever* rev = new Reciever();
Command* cmd1 = new ConcreteCommand1(rev);
Command* cmd2 = new ConcreteCommand2(rev);
Invoker* inv1 = new Invoker(cmd1);
Invoker* inv2 = new Invoker(cmd2);
inv1->Invoke();
inv2->Invoke();
return 0;
}
练习二
1.遥控器设结构图UML图:
2.实验运行结果截图:
3.代码分析
Aggregate.h
#ifndef _AGGREGATE_H_
#define _AGGREGATE_H_
class Iterator;
typedef int Object;
class Interator;
class Aggregate
{
public:
virtual ~Aggregate();
virtual Iterator* CreateIterator() = 0;
virtual Object GetItem(int idx) = 0;
virtual int GetSize() = 0;
protected:
Aggregate();
private:
};
class ConcreteAggregate:public Aggregate
{
public:
enum {SIZE = 100};
ConcreteAggregate();
~ConcreteAggregate();
Iterator* CreateIterator();
Object GetItem(int idx);
int GetSize();
protected:
private:
Object _objs[SIZE];
};
#endif //~_AGGREGATE_H_
Aggregate.cpp
#include "Aggregate.h"
#include "Iterator.h"
#include <iostream>
using namespace std;
Aggregate::Aggregate()
{
}
Aggregate::~Aggregate()
{
}
ConcreteAggregate::ConcreteAggregate()
{
for (int i = 0; i <=SIZE; i++)
_objs[i]= i+1;
}
ConcreteAggregate::~ConcreteAggregate()
{
}
Iterator* ConcreteAggregate::CreateIterator()
{
return new ConcreteIterator(this);
}
Object ConcreteAggregate::GetItem(int idx)
{
if (idx>=0&&idx<=this->GetSize())
return _objs[idx];
else
return -1;
}
int ConcreteAggregate::GetSize()
{
return SIZE;
}
Iterator.h
#ifndef _ITERATOR_H_
#define _ITERATOR_H_
class Aggregate;
typedef int Object;
class Iterator
{
public:
virtual ~Iterator();
virtual void First()=0;
virtual void Next()=0;
virtual void previous()=0;
virtual bool IsFirst()=0;
virtual bool IsDone()=0;
virtual Object CurrentItem()=0;
virtual void SetCurrentItem(int)=0;
protected:
Iterator();
private:
};
class ConcreteIterator:public Iterator
{
public:
ConcreteIterator(Aggregate* ag , int idx = 0);
~ConcreteIterator();
void First();
void Next();
void previous();
bool IsDone();
bool IsFirst();
Object CurrentItem();
void SetCurrentItem(int idx);
protected:
private:
Aggregate* _ag;
int _idx;
};
class ConcreteIterator1:public Iterator
{
public:
ConcreteIterator1(Aggregate* ag , int idx = 0);
~ConcreteIterator1();
void First();
void Next();
void previous();
bool IsDone();
bool IsFirst();
Object CurrentItem();
void SetCurrentItem(int idx);
protected:
private:
Aggregate* _ag;
int _idx;
};
#endif //~_ITERATOR_H_
Iterator.cpp
#include "Iterator.h"
#include "Aggregate.h"
#include <iostream>
using namespace std;
Iterator::Iterator()
{
}
Iterator::~Iterator()
{
}
ConcreteIterator::ConcreteIterator(Aggregate*
ag , int idx)
{
this->_ag = ag;
this->_idx= idx;
}
ConcreteIterator::~ConcreteIterator()
{
}
Object ConcreteIterator::CurrentItem()
{
if (_idx >= 0&&_idx < _ag->GetSize())
{
return _ag->GetItem(_idx);
}
else
{
return _ag->GetItem(-1);
}
}
void ConcreteIterator::SetCurrentItem(int idx)
{
if(!(20<=idx&&idx<=30)&&!(80<=idx&&idx<=90))
{
_idx = idx-1;
}
else
{
_idx = -1;
}
}
void ConcreteIterator::First()
{
_idx = 0;
}
void ConcreteIterator::Next()
{
if (_idx < _ag->GetSize())
{
if(_idx==18||_idx==78)
{
_idx+=12;
}
else
{
if(_idx==99)
{
_idx=0;
}
else
_idx++;
}
}
else
{
_idx=-1;
}
}
void ConcreteIterator::previous()
{
if (_idx > 0)
{
if(_idx==30||_idx==90)
{
_idx-=12;
}
else
{
_idx--;
}
}
else
{
if(_idx==0)
{
_idx=99;
}
else
_idx=-1;
}
}
bool ConcreteIterator::IsDone()
{
return (_idx == _ag->GetSize());
}
bool ConcreteIterator::IsFirst()
{
return (_idx == 1);
}
ConcreteIterator1::ConcreteIterator1(Aggregate*
ag , int idx)
{
this->_ag = ag;
this->_idx= idx;
}
ConcreteIterator1::~ConcreteIterator1()
{
}
Object ConcreteIterator1::CurrentItem()
{
if (_idx >= 0&&_idx < _ag->GetSize())
{
return _ag->GetItem(_idx);
}
else
{
return _ag->GetItem(-1);
}
}
void ConcreteIterator1::SetCurrentItem(int idx)
{
_idx = idx-1;
}
void ConcreteIterator1::First()
{
_idx = 0;
}
void ConcreteIterator1::Next()
{
if (_idx < _ag->GetSize())
{
if(_idx==99)
{
_idx=0;
}
else
_idx++;
}
}
void ConcreteIterator1::previous()
{
if (_idx > 0)
{
_idx--;
}
else
{
if(_idx==0)
{
_idx=99;
}
else
_idx=-1;
}
}
bool ConcreteIterator1::IsDone()
{
return (_idx == _ag->GetSize());
}
bool ConcreteIterator1::IsFirst()
{
return (_idx == 1);
}
Main.cpp
#include "Iterator.h"
#include "Aggregate.h"
#include <iostream>
using namespace std;
int main(int argc,char* argv[])
{
Aggregate* ag = new ConcreteAggregate();
int a,b,c,i;
Iterator* it;
cout<<"请输入1选择普通用户输入2选择VIP用户"<<endl;
cin>>a;
switch(a)
{
case 1:
cout<<"当前用户类型:普通用户"<<endl;
cout<<"功能:"<<endl;
cout<<"1:显示全部频道"<<endl;
cout<<"2:更换频道"<<endl;
cout<<"3:前一频道"<<endl;
cout<<"4:后一频道"<<endl;
cout<<"**********************************************"<<endl;
it = new ConcreteIterator(ag);
cout<<"请选择功能:"<<endl;
while(cin>>b)
{
switch(b)
{
case 1:cout<<"**********************************************频道列表**********************************************"<<endl;
for (it->SetCurrentItem(1),i=1; !(it->IsDone()),i<=78 ; it->Next(),i++)
{
cout<<it->CurrentItem()<<"\t";
if(i%10==0)
{
cout<<endl;
}
}
cout<<endl;
cout<<"**********************************************频道列表**********************************************"<<endl;
break;
case 2:cout<<"请输入要更换的频道:"<<endl;
cin>>c;
it->SetCurrentItem(c);
cout<<"当前频道:"<<it->CurrentItem()<<endl;
break;
case 3:it->previous();
cout<<"当前频道:"<<it->CurrentItem()<<endl;
break;
case 4:it->Next();
cout<<"当前频道:"<<it->CurrentItem()<<endl;
break;
}
}
case 2:
cout<<"当前用户类型:VIP用户"<<endl;
cout<<"功能:"<<endl;
cout<<"1:显示全部频道"<<endl;
cout<<"2:更换频道"<<endl;
cout<<"3:前一频道"<<endl;
cout<<"4:后一频道"<<endl;
cout<<"**********************************************"<<endl;
it = new ConcreteIterator1(ag);
cout<<"请选择功能:"<<endl;
while(cin>>b)
{
switch(b)
{
break;
case 1:cout<<"**********************************************频道列表**********************************************"<<endl;
for (it->SetCurrentItem(1),i=1; !(it->IsDone()),i<=100 ; it->Next(),i++)
{
cout<<it->CurrentItem()<<"\t";
if(i%10==0)
{
cout<<endl;
}
}
cout<<endl;
cout<<"**********************************************频道列表**********************************************"<<endl;
break;
case 2:cout<<"请输入要更换的频道:"<<endl;
cin>>c;
it->SetCurrentItem(c);
cout<<"当前频道:"<<it->CurrentItem()<<endl;
break;
case 3:it->previous();
cout<<"当前频道:"<<it->CurrentItem()<<endl;
break;
case 4:it->Next();
cout<<"当前频道:"<<it->CurrentItem()<<endl;
break;
}
}
}
return 0;
}