中山大学软件工程专业初级实训-会议议程管理Agenda

刚刚经历了两个星期的中级实训,那么这次实训的话毫无疑问地比大一初级实训简单了。在这里的话呢,还要感谢许多前辈给的神器。这里首先感谢@卡帕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
中山大学软件工程专业初级实训-会议议程管理Agenda_第1张图片
中山大学软件工程专业初级实训-会议议程管理Agenda_第2张图片
中山大学软件工程专业初级实训-会议议程管理Agenda_第3张图片
我们这一阶段主要实现三层架构中的数据访问层。首先来看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,就是创建会议的时候参与者是不存在的用户也能成功创建,希望有大神同学能帮我解决。

你可能感兴趣的:(软件工程实训,C++学习)