设计模式与XML(四)命令模式和遥控器模式(C++)

时间:2024-04-14 18:57:27

一、实验目的及要求

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图:

设计模式与XML(四)命令模式和遥控器模式(C++)

 

 

2.实验运行结果截图:

设计模式与XML(四)命令模式和遥控器模式(C++)

 

 

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图:

设计模式与XML(四)命令模式和遥控器模式(C++)

 

 

2.实验运行结果截图:

设计模式与XML(四)命令模式和遥控器模式(C++)

 

设计模式与XML(四)命令模式和遥控器模式(C++)

 

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;
}