设计模式之装饰模式
使用装饰模式来封装Nmea0183语句。
#ifndef DATAPARSER_H
#define DATAPARSER_H
#include <string>
#include <vector>
class DataParser
{
public:
DataParser();
virtual std::string fieldAnalysis(std::vector<std::string> vecStr) = 0;
};
#endif // DATAPARSER_H
#include "dataparser.h"
DataParser::DataParser()
{
}
#ifndef NMEAHANDLE_H
#define NMEAHANDLE_H
#include "dataparser.h"
class NmeaHandle : public DataParser
{
public:
NmeaHandle();
std::string fieldAnalysis(std::vector<std::string> vecStr) override;
};
#endif // NMEAHANDLE_H
#include "nmeahandle.h"
NmeaHandle::NmeaHandle()
{
}
std::string NmeaHandle::fieldAnalysis(std::vector<std::string> vecStr)
{
std::string stmt = "";
if(vecStr.size() > 0)
{
unsigned int i = 0;
for(const auto& item : vecStr)
{
stmt += item;
if(i == (vecStr.size() - 1)){
stmt += "*";
}
else{
stmt += ",";
}
i++;
}
}
return stmt;
}
#ifndef NMEADECORATOR_H
#define NMEADECORATOR_H
#include "dataparser.h"
class NmeaDecorator : public DataParser
{
public:
NmeaDecorator(DataParser* dp);
std::string calcChecksum(const std::string& sentence);
protected:
DataParser* m_dataParser;
};
#endif // NMEADECORATOR_H
#include "nmeadecorator.h"
#include <sstream>
#include <iomanip>
NmeaDecorator::NmeaDecorator(DataParser* dp) : m_dataParser(dp)
{
}
std::string NmeaDecorator::calcChecksum(const std::string &sentence)
{
int checksum = 0;
for (char c : sentence) {
if (c == '$') {
continue;
} else if (c == '*') {
break;
}
checksum ^= static_cast<int>(c);
}
std::stringstream ss;
ss << std::hex << std::uppercase << std::setw(2) << std::setfill('0') << checksum;
return ss.str();
}
#ifndef ZDA_STATEMENT_H
#define ZDA_STATEMENT_H
#include "nmeadecorator.h"
class ZDA_Statement : public NmeaDecorator
{
public:
ZDA_Statement(DataParser* dp);
std::string fieldAnalysis(std::vector<std::string> vecStr) override;
};
#endif // GPS_STATEMENT_H
#include "zda_statement.h"
ZDA_Statement::ZDA_Statement(DataParser* dp) : NmeaDecorator(dp)
{
}
std::string ZDA_Statement::fieldAnalysis(std::vector<std::string> vecStr)
{
std::string stmt = "$GPZDA,";
stmt += m_dataParser->fieldAnalysis(vecStr);
stmt += calcChecksum(stmt);
stmt += "\r\n";
return stmt;
}
#ifndef GGA_STATEMENT_H
#define GGA_STATEMENT_H
#include "nmeadecorator.h"
class GGA_Statement : public NmeaDecorator
{
public:
GGA_Statement(DataParser* dp);
std::string fieldAnalysis(std::vector<std::string> vecStr) override;
};
#endif // GGA_STATEMENT_H
#include "gga_statement.h"
GGA_Statement::GGA_Statement(DataParser* dp) : NmeaDecorator(dp)
{
}
std::string GGA_Statement::fieldAnalysis(std::vector<std::string> vecStr)
{
std::string stmt = "$GPGGZ,";
stmt += m_dataParser->fieldAnalysis(vecStr);
stmt += calcChecksum(stmt);
stmt += "\r\n";
return stmt;
}
#include <iostream>
#include "nmeahandle.h"
#include "gga_statement.h"
#include "zda_statement.h"
using namespace std;
int main()
{
std::vector<std::string> vecStr;
vecStr.push_back("110");
vecStr.push_back("108");
NmeaHandle nmeaHandle;
cout << nmeaHandle.fieldAnalysis(vecStr) << endl;
std::vector<std::string> vecZDAStr;
vecZDAStr.push_back("202711.56");
vecZDAStr.push_back("25");
vecZDAStr.push_back("12");
vecZDAStr.push_back("2023");
vecZDAStr.push_back("00");
vecZDAStr.push_back("00");
ZDA_Statement zdaStmt(&nmeaHandle);
cout << zdaStmt.fieldAnalysis(vecZDAStr) << endl;
std::vector<std::string> vecGGAStr;
vecGGAStr.push_back("202711.56");
vecGGAStr.push_back("1111.22");
vecGGAStr.push_back("N");
vecGGAStr.push_back("123.22");
vecGGAStr.push_back("E");
vecGGAStr.push_back("1");
vecGGAStr.push_back("3");
vecGGAStr.push_back("8.8");
vecGGAStr.push_back("100");
vecGGAStr.push_back("M");
vecGGAStr.push_back("0.0");
vecGGAStr.push_back("M");
vecGGAStr.push_back("0.0");
vecGGAStr.push_back("6");
GGA_Statement ggaStmt(&nmeaHandle);
cout << ggaStmt.fieldAnalysis(vecGGAStr) << endl;
return 0;
}