最近参加了软考,在准备考试过程中发现其中给出设计类图让通过指定的设计模式进行设计的题目对于练习C++和软件开发是一种不错的的方式,因为学校中的C++课程只讲C++语言,虽然也讲了封装、继承、多态等特性,但是缺少相应的练习,使得没有深入的认识和理解。同时类似于程序设计、软件工程的课程设计,其中概要设计、详细设计也都是文档写的很好看,最后编码从没按照设计中的内容来写。最终导致了学完C++,用的时候却不知从何下手。所以这里总结了全国计算机技术与软件专业技术资格(水平)考试参考用书系列中的部分题目,希望可以达到以下两个目的:
* 练习C++,掌握理解更多的特性,而不是只停留在掌握语法的阶段
* 提高软件开发方面的能力,主要是熟悉、学习基本的设计模式,学会如何设计并按照设计实现相应的编码
但需要特别指出的是设计模式还是推荐阅读这方面的经典书籍:设计模式 可复用面向对象软件的基础。我只是总结软考中的题目是因为题目可以让我们快速的对问题有所了解,并且我暂时也只是想练习C++,但如果想要对问题有系统、详细的了解还是需要读书。
Command(命令)模式
例:某灯具厂商欲生产一个灯具遥控器,该遥控器具有7个可编程的插槽,每个插槽都有开关按钮,对应着一个不同的灯。利用该遥控器能够统一控制房间内该厂商所有品牌灯具的开关,现采用Command(命令)模式实现该遥控器的软件部分。Command模式的类图如图所示。
/*************************************************
* Command Pattern
* Author : robocoder
* Date : 2016 - 11 - 13
* HomePage : https://robocoderhan.github.io/
* Email : robocoder@foxmail.com
*************************************************/
#include <iostream>
#include <string>
using namespace std;
class Light{
private:
string name;
public:
Light(string name){ this->name = name; }
void on(){ cout << name + " on" << endl; }
void off(){ cout << name + " off" << endl; }
};
class Command{
public:
virtual void execute(){}
};
class LightOnCommand :public Command{
private:
Light* light;
public:
LightOnCommand(Light* light){ this->light = light; }
void execute(){ light->on(); }
};
class LightOffCommand :public Command{
private:
Light* light;
public:
LightOffCommand(Light* light){ this->light = light; }
void execute(){ light->off(); }
};
class RemoteControl{
private:
Command* onCommands[7];
Command* offCommands[7];
public:
RemoteControl(){}
void setCommand(int slot, Command* onCommand, Command* offCommand){
onCommands[slot] = onCommand;
offCommands[slot] = offCommand;
}
void onButtonWasPushed(int slot){ onCommands[slot]->execute(); }
void offButtonWasPushed(int slot){ offCommands[slot]->execute(); }
};
int main() {
RemoteControl* remoteControl = new RemoteControl();
Light* livingRoomLight = new Light("Living Room");
Light* kitchenLight = new Light("Kitchen");
LightOnCommand* livingRoomLightOn = new LightOnCommand(livingRoomLight);
LightOffCommand* livingRoomLightOff = new LightOffCommand(livingRoomLight);
LightOnCommand* kitchenLightOn = new LightOnCommand(kitchenLight);
LightOffCommand* kitchenLightOff = new LightOffCommand(kitchenLight);
remoteControl->setCommand(0, livingRoomLightOn, livingRoomLightOff);
remoteControl->setCommand(1, kitchenLightOn, kitchenLightOff);
remoteControl->onButtonWasPushed(0);
remoteControl->offButtonWasPushed(0);
remoteControl->onButtonWasPushed(1);
remoteControl->offButtonWasPushed(1);
return 0;
}
Observer(观察者)模式
例:某实验室欲建立一个实验室环境监测系统,以显示实验室的温度、湿度以及洁净度等环境数据。当获取到最新的环境测量数据时,显示的环境数据能够更新。现在采用观察者(Observer)模式来开发该系统,观察者模式的类图如图所示。
/*************************************************
* Observer Pattern
* Author : robocoder
* Date : 2016 - 11 - 13
* HomePage : https://robocoderhan.github.io/
* Email : robocoder@foxmail.com
*************************************************/
#include <iostream>
#include <vector>
using namespace std;
class Observer{
public:
virtual void update(float temp, float humidity, float cleanness) = 0;
};
class Subject{
public:
virtual void registerObserver(Observer* o) = 0;
virtual void removeObserver(Observer* o) = 0;
virtual void notifyObserver() = 0;
};
class EnvironmentData : public Subject{
private:
vector<Observer*> observers;
float temperature, humidity, cleanness;
public:
void registerObserver(Observer* o){ observers.push_back(o); }
void removeObserver(Observer* o){}
void notifyObserver(){
for (vector<Observer*>::const_iterator it = observers.begin(); it != observers.end(); it++)
{
(*it)->update(temperature, humidity, cleanness);
}
}
void measurementsChanged(){ notifyObserver(); }
void setMeasurements(float temperature, float humidity, float cleanness){
this->temperature = temperature;
this->humidity = humidity;
this->cleanness = cleanness;
measurementsChanged();
}
};
class CurrentConditionsDisplay : public Observer{
private:
float temperature, humidity, cleanness;
Subject* envData;
public:
CurrentConditionsDisplay(Subject* envData){
this->envData = envData;
this->envData->registerObserver(this);
}
void update(float temperature, float humidity, float cleanness){
this->temperature = temperature;
this->humidity = humidity;
this->cleanness = cleanness;
display();
}
void display(){
cout << temperature << " " << humidity << " " << cleanness << endl;
}
};
int main(){
EnvironmentData* envData = new EnvironmentData();
CurrentConditionsDisplay* currentDisplay = new CurrentConditionsDisplay(envData);
envData->setMeasurements(80, 65, 30.4f);
return 0;
}
Bridge(桥接)模式
例:欲开发一个绘图软件,要求使用不同的绘图程序绘制不同的图形。以绘制直线和圆形为例,对应的绘图程序如表所示。
^-^ | DP1 | DP2 |
---|---|---|
绘制直线 | draw_a_line(x1,y1,x2,y2) | drawline(x1,y1,x2,y2) |
绘制圆 | draw_a_circle(x,y,r) | drawcircle(x,y,r) |
该绘制软件的扩展性要求,将不断扩充新的图形和新的绘图程序。为了避免出现类爆炸的情况,现采用桥接(Bridge)模式来实现上述要求,得到如图所示的类图。
/*************************************************
* Bridge Pattern
* Author : robocoder
* Date : 2016 - 11 - 15
* HomePage : https://robocoderhan.github.io/
* Email : robocoder@foxmail.com
*************************************************/
#include <iostream>
using namespace std;
class DP1{
public:
static v