刚刚经历了两个星期的中级实训,那么这次实训的话毫无疑问地比大一初级实训简单了。在这里的话呢,还要感谢许多前辈给的神器。这里首先感谢@卡帕kalper前辈和@jayjiahua前辈。下面给出两个中级实训的神器。那么经历了一次相对来说比较轻松的实训之后呢,感觉大一时候的初级实训真是太辛苦了,而且的话缺少神器。所以决定向以上两位大神学习,给迷茫中的学弟学妹们一些指引,这里借用前辈的一句话,因为平时在完成一些任务的时候,深刻感受到前人经验带给自己的便利,在此我也分享下自己的东西,希望能给后人乘荫吧~!
http://blog.csdn.net/zkp0601/article/details/38564501
https://github.com/jayjiahua/GridWorld
实训具体内容请戳http://my.ss.sysu.edu.cn/wiki/pages/viewpage.action?pageId=430538815
我们初级实训主要使用C++语言写出一个会议议程管理系统Agenda。由于时间过去比较久了记忆不太清楚了,而且写码时间不长(只写了一天),因为写的比较仓促,所以声明和实现都写在一个文件里了,可能的话会还有一些些的Bug,而且没有什么注释,大家阅读起来可能比较困难,如果对源码有疑问或者有帮我找出Bug的同学,欢迎给我发邮件,邮箱:[email protected]
想自己学习代码的同学请直接往下滑,或者戳下面的链接:
https://github.com/yang20150928/Agenda/tree/master/src
下面给出会议议程管理系统Agenda需求文档和三层架构介绍,github链接中给出了本次实训所有头文件。
http://my.ss.sysu.edu.cn/wiki/download/attachments/304840949/xuqiu.pdf?version=1&modificationDate=1404036510000
http://blog.csdn.net/hanxuemin12345/article/details/8544957
https://github.com/ss14agenda/Agenda/tree/master/src
接下来我们来说第一阶段。那么第一阶段的话呢我们就是要完成Date 类,User 类,Meeting 类,Storage类的代码实现,下面给出这其中几个类的UML图(缺少Date类的UML图)和需求链接和Date类的需求,这里的Storage类我按照当时大一的要求,使用的是JSON的存储格式,由于C++没有JSON的库,所以这部分代码写起来比较麻烦(也花了我很多时间)。
http://my.ss.sysu.edu.cn/wiki/download/attachments/167936064/%E5%8F%82%E9%98%85%E8%B5%84%E6%96%99_User+class+diagram+and+code.pdf?version=1&modificationDate=1343288053000
http://my.ss.sysu.edu.cn/wiki/download/attachments/167936064/%E5%8F%82%E9%98%85%E8%B5%84%E6%96%99_Meeting+class+diagram.pdf?version=1&modificationDate=1343617818000
http://my.ss.sysu.edu.cn/wiki/download/attachments/304840949/Storage.png?version=3&modificationDate=1403996090000
http://my.ss.sysu.edu.cn/wiki/download/attachments/167936064/%E5%AF%B9%E4%BA%8E%E4%BC%9A%E8%AE%AE%E6%97%B6%E9%97%B4%E6%98%BE%E7%A4%BA%E7%9A%84%E9%A2%9D%E5%A4%96%E8%A1%A5%E5%85%85.pdf?version=2&modificationDate=1378093428000
我们这一阶段主要实现三层架构中的数据访问层。首先来看User类,User类的话有四个私有属性name, password, email, phone, User类的方法就是对这些属性的set和get。Meeting类也是类似。Date类的话还有三个静态函数实现起来比较麻烦,而且还需要运算符重载。
Storage类中通过操作系统文件的读写完成数据的存储。Storage类采用单例模式设计,只有一个实例,也就是所谓的Singonton。他有一个instance指针实例变量,而且构造函数就是私有的,只能通过getInstance()方法取回实例,所以getInstance()方法思路大致如下:如果属性instance为空,instance就new一个Storage实例,否则返回instance。Storage还有两个list属性用于存储user和meeting。由于在会议议程管理系统Agenda启动时,要从文件中读取数据,所以Storage类的构造函数中调用readFromFile()方法,readFromFile()方法从文件中读取数据,sync是同步的缩写,所以在sync()方法中我们进行数据的同步,也是将内存中的数据写入磁盘中的文件,所以调用writeToFile()方法。其余的query,update,delete方法就是根据传入filter函数进行处理。由于我们不需要在Storage类中进行逻辑判断,所以在create方法中我们直接调用list中的push_back()方法。query方法遍历整个list,如果filter返回值为真,就插入新list中,最好返回新list。update方法也是遍历整个list,如果filter返回值为真,就用switcher函数进行更新,返回更新的数目。delete方法也是遍历整个list,如果filter返回值为真,调用list中erase()方法删除,返回删除的数目。
下面给出实现这四个类的代码:
#ifndef __USER_H__
#define __USER_H__
#include
using namespace std;
class User {
public:
User() {}
User(string userName, string userPassword,
string userEmail, string userPhone) {
name_ = userName;
password_ = userPassword;
email_ = userEmail;
phone_ = userPhone;
}
string getName() const {
return name_;
}
void setName(string name) {
name_ = name;
}
string getPassWord() const {
return password_;
}
void setPassword(string password) {
password_ = password;
}
string getEmail() const {
return email_;
}
void setEmail(string email) {
email_ = email;
}
string getPhone() const {
return phone_;
}
void setPhone(string phone) {
phone_ = phone;
}
private:
string name_;
string password_;
string email_;
string phone_;
};
#endif
#ifndef __DATE_H__
#define __DATE_H__
#include
#include
using namespace std;
class Date {
public:
Date() {}
Date(int y, int m, int d, int h, int mi) {
year_ = y;
month_ = m;
day_ = d;
hour_ = h;
minute_ = mi;
}
int getYear(void) const {
return year_;
}
void setYear(int year) {
year_ = year;
}
int getMonth(void) const {
return month_;
}
void setMonth(int month) {
month_ = month;
}
int getDay(void) const {
return day_;
}
void setDay(int day) {
day_ = day;
}
int getHour(void) const {
return hour_;
}
void setHour(int hour) {
hour_ = hour;
}
int getMinute(void) const {
return minute_;
}
void setMinute(int minute) {
minute_ = minute;
}
static bool isValid(Date date) {
if (!(date.getYear() >= 1000 && date.getYear() <= 9999))
return false;
if (!(date.getMonth() >= 1 && date.getMonth() <= 12))
return false;
if (date.getMonth() != 2) {
switch (date.getMonth()) {
case 1:
case 3:
case 5:
case 7:
case 8:
case 10:
case 12:
if (!(date.getDay() >= 1 && date.getDay() <= 31))
return false;
break;
case 4:
case 6:
case 9:
case 11:
if (!(date.getDay() >= 1 && date.getDay() <= 30))
return false;
break;
default:
break;
}
}
else if (Isleap(date)) {
if (!(date.getDay() >= 1 && date.getDay() <= 29))
return false;
}
else {
if (!(date.getDay() >= 1 && date.getDay() <= 28))
return false;
}
if (!(date.getHour() >= 0 && date.getHour() <= 23))
return false;
if (!(date.getMinute() >= 0 && date.getMinute() <= 59))
return false;
return true;
}
static Date stringToDate(std::string dateString) {
stringstream ss;
int y, m, d, h, mi;
char t;
ss << dateString;
ss >> y >> t >> m >> t
>> d >> t >> h >> t >> mi;
return Date(y, m, d, h, mi);
}
static std::string dateToString(Date date) {
stringstream ss;
ss << date.getYear() << "-"
<< supplyZero(date.getMonth()) << "-"
<< supplyZero(date.getDay()) << "/"
<< supplyZero(date.getHour()) << ":"
<< supplyZero(date.getMinute());
return ss.str();
}
Date &operator=(const Date& date) {
setYear(date.getYear());
setMonth(date.getMonth());
setDay(date.getDay());
setHour(date.getHour());
setMinute(date.getMinute());
return *this;
}
bool operator==(const Date& date) const {
return getYear() == date.getYear() &&
getMonth() == date.getMonth() &&
getDay() == date.getDay() &&
getHour() == date.getHour() &&
getMinute() == date.getMinute();
}
bool operator>(const Date& date) const {
return getYear() > date.getYear() ? true :
getMonth() > date.getMonth() ? true :
getDay() > date.getDay() ? true :
getHour() > date.getHour() ? true : false;
}
bool operator<(const Date& date) const {
return !(*this > date) && !(*this == date);
}
bool operator>=(const Date& date) const {
return !(*this < date);
}
bool operator<=(const Date& date) const {
return !(*this > date);
}
private:
int year_;
int month_;
int day_;
int hour_;
int minute_;
static bool Isleap(Date date) {
return (date.getYear() / 4 == 0 && date.getYear() / 100 != 0)
|| date.getYear() / 400 == 0;
}
static string supplyZero(int arg) {
stringstream ss;
if (arg < 10) {
ss << "0" << arg;
}
else {
ss << arg;
}
return ss.str();
}
};
#endif
#ifndef __MEETING_H__
#define __MEETING_H__
#include "Date.h"
using namespace std;
class Meeting {
public:
Meeting() {}
Meeting(std::string sponsor, std::string participator,
Date startTime, Date endTime, std::string title) {
sponsor_ = sponsor;
participator_ = participator;
startDate_ = startTime;
endDate_ = endTime;
title_ = title;
}
std::string getSponsor(void) const {
return sponsor_;
}
void setSponsor(std::string sponsor) {
sponsor_ = sponsor;
}
std::string getParticipator(void) const {
return participator_;
}
void setParticipator(std::string participator) {
participator_ = participator;
}
Date getStartDate(void) const {
return startDate_;
}
void setStartDate(Date startTime) {
startDate_ = startTime;
}
Date getEndDate(void) const {
return endDate_;
}
void setEndDate(Date endTime) {
endDate_ = endTime;
}
std::string getTitle(void) const {
return title_;
}
void setTitle(std::string title) {
title_ = title;
}
private:
std::string sponsor_;
std::string participator_;
Date startDate_;
Date endDate_;
std::string title_;
};
#endif
#ifndef __STORAGE_H__
#define __STORAGE_H__
#define DISALLOW_COPY_AND_ASSIGN(TypeName) \
TypeName(const TypeName&); \
void operator=(const TypeName&)
#include
#include
#include
#include
#include
#include "User.h"
#include "Meeting.h"
using namespace std;
class Storage {
private:
static Storage *instance_;
DISALLOW_COPY_AND_ASSIGN(Storage);
Storage() {
readFromFile("agenda.data");
}
// storage structure with list, or you have better structures
// e.g. balanced tree
std::list userList_;
std::list meetingList_;
// File IO
bool readFromFile(const char *fpath) {
ifstream fin(fpath);
if (!fin.is_open())
return false;
int userCount, meetingCount;
string str;
stringstream ss;
fin >> str;
str = str.substr(str.find("total:") + 6);
ss << str;
ss >> userCount;
ss.str("");
for (int i = 0; i < userCount; i++) {
fin >> str;
userList_.push_back(JSONToUser(str));
}
fin >> str;
str = str.substr(str.find("total:") + 6);
ss << str;
ss >> meetingCount;
for (int i = 0; i < meetingCount; i++) {
fin >> str;
meetingList_.push_back(JSONToMeeting(str));
}
return true;
}
bool writeToFile(const char *fpath) {
ofstream fout(fpath);
if (!fout.is_open())
return false;
fout << "{colletion:\"User\",total:" << userList_.size() << "}\n";
for (auto itr = userList_.begin(); itr != userList_.end(); itr++) {
fout << UserToJSON(*itr) << endl;
}
fout << "{colletion:\"Meeting\",total:" << meetingList_.size() << "}\n";
for (auto itr = meetingList_.begin(); itr != meetingList_.end(); itr++) {
fout << MeetingToJSON(*itr) << endl;
}
return true;
}
string UserToJSON(const User& user) {
stringstream ss;
ss << "{name:" << "\"" << user.getName() << "\","
<< "password:" << "\"" << user.getPassWord() << "\","
<< "email:" << "\"" << user.getEmail() << "\","
<< "phone:" << "\"" << user.getPhone() << "\"}";
return ss.str();
}
string MeetingToJSON(const Meeting& meeting) {
stringstream ss;
ss << "{sponsor:" << "\"" << meeting.getSponsor() << "\","
<< "partipator:" << "\"" << meeting.getParticipator() << "\","
<< "sdate:" << "\"" << Date::dateToString(meeting.getStartDate()) << "\","
<< "edate:" << "\"" << Date::dateToString(meeting.getEndDate()) << "\","
<< "title:" << "\"" << meeting.getTitle() << "\"}";
return ss.str();
}
User JSONToUser(const string& json) {
string name, password, email, phone;
int pos, len;
pos = json.find("name:\"") + 6;
len = json.find("\",password") - pos;
name = json.substr(pos, len);
pos = json.find("password:\"") + 10;
len = json.find("\",email") - pos;
password = json.substr(pos, len);
pos = json.find("email:\"") + 7;
len = json.find("\",phone") - pos;
email = json.substr(pos, len);
pos = json.find("phone:\"") + 7;
len = json.find("\"}") - pos;
phone = json.substr(pos, len);
return User(name, password, email, phone);
}
Meeting JSONToMeeting(const string& json) {
string sponsor, partipator, sdate, edate, title;
int pos, len;
pos = json.find("sponsor:\"") + 9;
len = json.find("\",partipator") - pos;
sponsor = json.substr(pos, len);
pos = json.find("partipator:\"") + 12;
len = json.find("\",sdate") - pos;
partipator = json.substr(pos, len);
pos = json.find("sdate:\"") + 7;
len = json.find("\",edate") - pos;
sdate = json.substr(pos, len);
pos = json.find("edate:\"") + 7;
len = json.find("\",title") - pos;
edate = json.substr(pos, len);
pos = json.find("title:\"") + 7;
len = json.find("\"}") - pos;
title = json.substr(pos, len);
return Meeting(sponsor, partipator,
Date::stringToDate(sdate), Date::stringToDate(edate), title);
}
public:
// singleton
static Storage *getInstance(void) {
if (instance_ == nullptr)
instance_ = new Storage();
return instance_;
}
~Storage() {}
// CRUD for User & Meeting
// using C++11 Function Template and Lambda Expressions
void createUser(const User& user) {
userList_.push_back(user);
}
std::list queryUser(std::function<bool(const User&)> filter) {
list returnList;
for (auto itr = userList_.begin(); itr != userList_.end(); itr++) {
if (filter(*itr)) {
returnList.push_back(*itr);
}
}
return returnList;
}
// return found users
int updateUser(std::function<bool(const User&)> filter,
std::function<void(User&)> switcher) {
int count = 0;
for (auto itr = userList_.begin(); itr != userList_.end(); itr++) {
if (filter(*itr)) {
switcher(*itr);
count++;
}
}
return count;
}
// return the number of updated users
int deleteUser(std::function<bool(const User&)> filter) {
int count = 0;
for (auto itr = userList_.begin(); itr != userList_.end(); itr++) {
if (filter(*itr)) {
userList_.push_back(*itr);
count++;
}
}
return count;
}
// return the number of deleted users
void createMeeting(const Meeting& meeting) {
meetingList_.push_back(meeting);
}
std::list queryMeeting(
std::function<bool(const Meeting&)> filter) {
list returnList;
for (auto itr = meetingList_.begin(); itr != meetingList_.end(); itr++) {
if (filter(*itr)) {
returnList.push_back(*itr);
}
}
return returnList;
}
// return found meetings
int updateMeeting(std::function<bool(const Meeting&)> filter,
std::function<void(Meeting&)> switcher) {
int count = 0;
for (auto itr = meetingList_.begin(); itr != meetingList_.end(); itr++) {
if (filter(*itr)) {
switcher(*itr);
count++;
}
}
return count;
}
// return the number of updated meetings
int deleteMeeting(std::function<bool(const Meeting&)> filter) {
int count = 0;
for (auto itr = meetingList_.begin(); itr != meetingList_.end(); itr++) {
if (filter(*itr)) {
meetingList_.erase(itr);
count++;
}
}
return count;
}
// return the number of deleted meetings
// File IO
bool sync(void) {
return writeToFile("agenda.data");
}
};
Storage* Storage::instance_ = nullptr;
#endif
那么阶段二的话呢,我们就要完成完成AgendaService类(应用逻辑实体)和AgendaUI类(终端交互界面)的实现了。下面给出代码实现。这里要注意的是lambda函数的运用还有就是
1会议的title是唯一的。
2不允许创建会议为一个时间点,比如从8点到8点
3关于找出一个时间段内的会议,只要有时间点重叠,都要算上去。
AgendaService类中的私有属性是Storage的实例,所有在startAgenda()方法中取回实例,那么在quitAgenda()进行数据更新,所以分别在构造函数和析构函数中调用他们。至于其他的list, query, create, delete等的方法我们通过lambda函数给定自己的filter,然后调用Storage类中相关方法就行了。
下面先给出Agenda的接口约束:
http://my.ss.sysu.edu.cn/wiki/pages/viewpage.action?pageId=431849490
AgendaUI类中,有三个私有属性,userName, userPassword, 和一个AgendaService对象,userName和userPassword应该就是当前用户的姓名和密码了,所以我们在userLogIn()和userRegister()方法中对他们复制,由于只有用户登录之后才能进行管理操作,所以我们在userLogIn()和userRegister()中加入以下的这个语句while(executeOperation(getOperation()));
用来循环处理管理操作,由于用户登出以及用户删除自己之后不能在进行管理操作,所以在executeOperation()方法中调用这些行为并且返回false。这样的话我们在OperationLoop()方法中只处理登录前的循环操作就可以了。其余的方法大致就是先向用户请求输入,然后调用AgendaService中的方法就行了。
#ifndef __AGENDASERVICE_H__
#define __AGENDASERVICE_H__
#include "Storage.h"
#include
#include
using namespace std;
class AgendaService {
public:
AgendaService() {
startAgenda();
}
~AgendaService() {
quitAgenda();
}
bool userLogIn(std::string userName, std::string password) {
auto filter = [userName, password](const User& user) {
return user.getName() == userName && user.getPassWord() == password;
};
return storage_->queryUser(filter).size() > 0;
}
bool userRegister(std::string userName, std::string password,
std::string email, std::string phone) {
auto filter = [userName, password, email, phone](const User& user) {
return user.getName() == userName || user.getEmail() == email
|| user.getPhone() == phone;
};
if (storage_->queryUser(filter).size() == 0) {
storage_->createUser(User(userName, password, email, phone));
return true;
}
return false;
}
bool deleteUser(std::string userName, std::string password) {
auto filter = [userName, password](const User& user) {
return user.getName() == userName && user.getPassWord() == password;
};
if (storage_->deleteUser(filter) > 0) {
deleteAllMeetings(userName);
return true;
}
return false;
}
// a user can only delete itself
std::list listAllUsers(void) {
auto filter = [](const User& user) {
return true;
};
return storage_->queryUser(filter);
}
bool createMeeting(std::string userName, std::string title,
std::string participator,
std::string startDate, std::string endDate) {
if (!Date::isValid(Date::stringToDate(startDate))
|| !Date::isValid(Date::stringToDate(endDate))) {
return false;
}
auto filter1 = [participator](const User& user) {
return user.getName() == participator;
};
if (storage_->queryUser(filter1).size() <= 0) {
return false;
}
auto filter2 = [title](const Meeting& meeting) {
return meeting.getTitle() == title;
};
if (storage_->queryMeeting(filter2).size() > 0) {
return false;
}
if (meetingQuery(userName, startDate, endDate).size() > 0
|| meetingQuery(participator, startDate, endDate).size() > 0) {
return false;
}
storage_->createMeeting(Meeting(userName, participator,
Date::stringToDate(startDate), Date::stringToDate(endDate), title));
return true;
}
std::list meetingQuery(std::string userName, std::string title) {
auto filter = [userName, title](const Meeting& meeting) {
return (meeting.getSponsor() == userName ||
meeting.getParticipator() == userName) &&
meeting.getTitle() == title;
};
return storage_->queryMeeting(filter);
}
std::list meetingQuery(std::string userName, std::string startDate,
std::string endDate) {
auto filter = [userName, startDate, endDate](const Meeting& meeting) {
return (meeting.getSponsor() == userName || meeting.getParticipator() == userName) &&
((meeting.getStartDate() >= Date::stringToDate(startDate) &&
meeting.getStartDate() <= Date::stringToDate(endDate) ||
(meeting.getEndDate() >= Date::stringToDate(startDate) &&
meeting.getEndDate() <= Date::stringToDate(endDate)) ||
(meeting.getStartDate() <= Date::stringToDate(startDate) &&
meeting.getEndDate() >= Date::stringToDate(endDate))));
};
return storage_->queryMeeting(filter);
}
std::list listAllMeetings(std::string userName) {
auto filter = [userName](const Meeting& meeting) {
return meeting.getSponsor() == userName ||
meeting.getParticipator() == userName;
};
return storage_->queryMeeting(filter);
}
std::list listAllSponsorMeetings(std::string userName) {
auto filter = [userName](const Meeting& meeting) {
return meeting.getSponsor() == userName;
};
return storage_->queryMeeting(filter);
}
std::list listAllParticipateMeetings(std::string userName) {
auto filter = [userName](const Meeting& meeting) {
return meeting.getParticipator() == userName;
};
return storage_->queryMeeting(filter);
}
bool deleteMeeting(std::string userName, std::string title) {
auto filter = [userName, title](const Meeting& meeting) {
return (meeting.getSponsor() == userName ||
meeting.getParticipator() == userName) &&
meeting.getTitle() == title;
};
return storage_->deleteMeeting(filter) > 0;
}
bool deleteAllMeetings(std::string userName) {
auto filter = [userName](const Meeting& meeting) {
return meeting.getSponsor() == userName ||
meeting.getParticipator() == userName;
};
return storage_->deleteMeeting(filter) > 0;
}
void startAgenda(void) {
storage_ = Storage::getInstance();
}
void quitAgenda(void) {
storage_->sync();
}
private:
Storage *storage_;
};
#endif
#ifndef __AGENDAUI_H__
#define __AGENDAUI_H__
#include "AgendaService.h"
#include
#include
class AgendaUI {
public:
AgendaUI() {
startAgenda();
}
void OperationLoop(void) {
string operation;
do {
cout << "________________________________Agenda________________________________\n"
<< "Action :\n"
<< "l - log in Agenda by user name and password\n"
<< "r - register an Agenda account\n"
<< "q - quit Agenda\n"
<< "______________________________________________________________________\n"
<< "\n" << "Agenda : ~$ ";
cin >> operation;
switch(operation[0]) {
case 'l':
userLogIn();
break;
case 'r':
userRegister();
break;
case 'q':
quitAgenda();
break;
default:
break;
}
} while(operation[0] != 'q');
}
private:
// task functions
void startAgenda(void) {
agendaService_.startAgenda();
}
std::string getOperation() {
string operation;
cout << "________________________________Agenda________________________________\n"
<< "Action :\n"
<< "o - log out Agenda\n"
<< "dc - delete Agenda account\n"
<< "lu - list all Agenda user\n"
<< "cm - create a meeting\n"
<< "la - list all meetings\n"
<< "las - list all sponsor meetings\n"
<< "lap - list all participate meetings\n"
<< "qm - query meeting by title\n"
<< "qt - query meeting by time interval\n"
<< "dm - delete meeting by title\n"
<< "da - delete all meetings\n"
<< "______________________________________________________________________\n"
<< "\n" << "Agenda@" << userName_ << " :# ";
cin >> operation;
return operation;
}
bool executeOperation(std::string op) {
if (op == "o") {
userLogOut();
return false;
}
else if (op == "dc") {
deleteUser();
return false;
}
else if (op == "lu") {
listAllUsers();
return true;
}
else if (op == "cm") {
createMeeting();
return true;
}
else if (op == "la") {
listAllMeetings();
return true;
}
else if (op == "las") {
listAllSponsorMeetings();
return true;
}
else if (op == "lap") {
listAllParticipateMeetings();
return true;
}
else if (op == "qm") {
queryMeetingByTitle();
return true;
}
else if (op == "qt") {
queryMeetingByTimeInterval();
return true;
}
else if (op == "dm") {
deleteMeetingByTitle();
return true;
}
else if (op == "da") {
deleteAllMeetings();
return true;
}
return true;
}
void userLogIn(void) {
string userName, password;
cout << "[log in] [user name] [password]\n"
<< "[log in] ";
cin >> userName >> password;
if (agendaService_.userLogIn(userName, password)) {
userName_ = userName;
userPassword_ = password;
cout << "[log in] succeed!\n";
while(executeOperation(getOperation()));
}
else {
cout << "[error] log in fail!\n";
}
}
void userRegister(void) {
string userName, password, email, phone;
cout << "[register] [user name] [password] [email] [phone]\n"
<< "[register] ";
cin >> userName >> password >> email >> phone;
if (agendaService_.userRegister(userName, password, email, phone)) {
userName_ = userName;
userPassword_ = password;
cout << "[register] succeed!\n";
while(executeOperation(getOperation()));
}
else {
cout << "[error] register fail!\n";
}
}
void quitAgenda(void) {
agendaService_.quitAgenda();
}
void userLogOut(void) {
userName_.clear();
userPassword_.clear();
}
void deleteUser(void) {
agendaService_.deleteUser(userName_, userPassword_);
userLogOut();
}
void listAllUsers(void) {
printUsers(agendaService_.listAllUsers());
}
void createMeeting(void) {
string title, participator, startDate, endDate;
cout << "[create meeting] [title] [participator] [start time(yyyy-mm-dd/hh:mm)] [end time(yyyy-mm-dd/hh:mm)]\n"
<< "[create meeting] ";
cin >> title >> participator >> startDate >> endDate;
if (agendaService_.createMeeting(userName_, title, participator, startDate, endDate)) {
cout << "[create meeting] succeed!\n";
}
else {
cout << "[error] create meeting fail!\n";
}
}
void listAllMeetings(void) {
printMeetings(agendaService_.listAllMeetings(userName_));
}
void listAllSponsorMeetings(void) {
printMeetings(agendaService_.listAllSponsorMeetings(userName_));
}
void listAllParticipateMeetings(void) {
printMeetings(agendaService_.listAllParticipateMeetings(userName_));
}
void queryMeetingByTitle(void) {
string title;
cout << "[query meeting] [title]\n"
<< "[query meeting] ";
cin >> title;
printMeetings(agendaService_.meetingQuery(userName_, title));
}
void queryMeetingByTimeInterval(void) {
string startDate, endDate;
cout << "[query meetings] [start time(yyyy-mm-dd/hh:mm)] [end time(yyyy-mm-dd/hh:mm)]\n"
<< "[query meetings] ";
cin >> startDate >> endDate;
printMeetings(agendaService_.meetingQuery(userName_, startDate, endDate));
}
void deleteMeetingByTitle(void) {
string title;
cout << "[delete meeting] [title]\n"
<< "[delete meeting] ";
cin >> title;
if (agendaService_.deleteMeeting(userName_, title)) {
cout << "[delete meeting by title] succeed!\n";
}
else {
cout << "[error] delete meeting fail!\n";
}
}
void deleteAllMeetings(void) {
agendaService_.deleteAllMeetings(userName_);
cout << "[delete all meetings] succeed!\n";
}
void printMeetings(std::list meetings) {
cout << "title\t" << "sponsor\t" << "participator\t"
<< "start time\t" << "end time\n";
for (auto itr = meetings.begin(); itr != meetings.end(); itr++) {
cout << itr->getTitle() << "\t"
<< itr->getSponsor() << "\t"
<< itr->getParticipator() << "\t"
<< Date::dateToString(itr->getStartDate()) << "\t"
<< Date::dateToString(itr->getEndDate()) << "\n";
}
}
void printUsers(std::list users) {
cout << "name\t" << "email\t" << "phone\n";
for (auto itr = users.begin(); itr != users.end(); itr++) {
cout << itr->getName() << "\t"
<< itr->getEmail() << "\t"
<< itr->getPhone() << "\n";
}
}
// dates
std::string userName_;
std::string userPassword_;
AgendaService agendaService_;
};
#endif
最后给出cpp文件的源码
#include "AgendaUI.h"
AgendaUI aui;
int main() {
aui.OperationLoop();
return 0;
}
由于这次写码和写文时间比较仓促,有很多代码没有经过测试,所以仅供大家参考,不过正常的run还是可以的,而且可能有代码可读性差的问题。另外我最后测试也没能解决的一个Bug,就是创建会议的时候参与者是不存在的用户也能成功创建,希望有大神同学能帮我解决。