You must have heard alipay(“Zhi Fu Bao” for Chinese). Now in this topic, we will do a series of practice to develop such a online payment system. This Time we are going to focus on the core of the system, the user part. If you have an account in alipay, you will have some basic knowledge about the architecture of the class, user.
Requirements
I have already build a hpp file for the class architecture, and your job is to implement the specific functions.
In order to prevent name conflicts, I have already declared a namespace for alipay. You should notice that while you are going to coding.
There will be some more details:
// username should be a combination of letters and numbers and the length should be in [6,20]
// correct: [“Alice1995”, “Heart2you”, “love2you”, “5201314”]
// incorrect: [“222@_@222”, “12306”, “abc12?”]
std::string username;
// password should be a combination of letters and numbers and the length should be in [8,20]
// correct: [“12345678”, “abc00000000”]
// incorrect: [“123”, “21?=_=?12”]
std::string password;
// phone should be a number and the length should be fixed 13
// correct: [“8618819473230”]
// incorrect: [“110”, “330”]
std::string phone;
Gender::Gender gender;
// because soil-rich use this system, so no decimal.
long long int balance;
// auxiliary function for format checking
inline bool verifyPasswordFormat(const std::string & password);
inline bool verifyUsernameFormat(const std::string & username);
inline bool verifyPhoneFormat(const std::string & phone);
// Because of the mistake of the architect of alibaba,
// all the parameters of these function use c strings(char *).
// you are smart, the transformation is not a problem
// if the input is a valid username, set it and return true
bool setUsername(const char * username);
// You should confirm the old password and the new_password’s format
bool setPassword(const char * new_password, const char * old_password);
bool setPhone(const char * new_phone);
// You can not set the Gender to unknown again
bool setGender(Gender::Gender gender);
std::string getUsername(void);
std::string getPhone(void);
alipay::Gender::Gender getGender(void);
long long int getMoneyAmount(const char * password);
bool deposit(long long int amount);
// password check is needed when withdraw
bool withdraw(long long int amount, const char * password);
Deep Thinking and Discuss
What’s the disadvantages of this design?
Why “using namespace std” is not a good way in c++ programming?
More
If you have any ideas or thoughts about alipay system. Just leave a message below or send me a mail.
Next we will have some practice which is more detailed with the teaching process.
Hint:
建議大家好好復習上學期c語言有關函數原型的相關知識,麼麼哒。
main.cpp
#include "user.hpp" #include "test.hpp" int main() { unittest::TEST t; t.runAllCases(); return 0; } ``` test.hpp ```cpp #ifndef TEST_H_ #define TEST_H_ #include "user.hpp" #include#include using std::cin; using std::cout; using std::endl; using std::cerr; using std::string; namespace unittest { class TEST { public: // complete legal operations void TestCase1() { cout << "Test1" << endl; alipay::User u; char username[20]; cin >> username; u.setUsername(username) ? cout << "Pass" : cout << "Fail"; cout << "\tsetting a legal username." << username << endl; char password[20]; cin >> password; u.setPassword(password, "") ? cout << "Pass" : cout << "Fail"; cout << "\tsetting a legal password for a blank password." << password << endl; char phone[20]; cin >> phone; u.setPhone(phone) ? cout << "Pass" : cout << "Fail"; cout << "\tsetting a legal phone." << phone << endl; int gender; cin >> gender; u.setGender(gender == 0 ? alipay::Gender::Female : alipay::Gender::Male) ? cout << "Pass" : cout << "Fail"; cout << "\tsetting a legal gender: " << (gender == 0 ? "Female." : "Male.") << endl; string username_s = u.getUsername(); username_s == username ? cout << "Pass" : cout << "Fail"; cout << "\tusername should be equal: (" << username << "," << username_s << ")." << endl; string phone_s = u.getPhone(); phone == phone_s ? cout << "Pass" : cout << "Fail"; cout << "\tphone should be equal: (" << phone << "," << phone_s << ")." << endl; int money; cin >> money; u.deposit(money) ? cout << "Pass" : cout << "Fail"; cout << "\ttry to deposit." << endl; cin >> money; u.withdraw(money, password) ? cout << "Pass" : cout << "Fail"; cout << "\ttry to withdraw." << endl; cout << endl; } // complete illegal operations void TestCase2() { cout << "Test2" << endl; alipay::User u; char wrong_username[20]; cin >> wrong_username; !u.setUsername(wrong_username) ? cout << "Pass" : cout << "Fail"; cout << "\tsetting an illegal username." << wrong_username << endl; char wrong_phone[20]; cin >> wrong_phone; !u.setPhone(wrong_phone) ? cout << "Pass" : cout << "Fail"; cout << "\tsetting an illegal phone." << wrong_phone << endl; char wrong_password[20]; cin >> wrong_password; !u.setPassword(wrong_password, "") ? cout << "Pass" : cout << "Fail"; cout << "\tsetting an illegal password." << wrong_password << endl; u.setPassword("20482048123", ""); !u.setPassword("123", "123") ? cout << "Pass" : cout << "Fail"; cout << "\tsetting a new password using wrong old password." << endl; cout << endl; } // complete illegal operations2 void TestCase3() { cout << "Test3" << endl; alipay::User u; u.setPassword("123456789", ""); !u.withdraw(-1000, "123456789") ? cout << "Pass" : cout << "Fail"; cout << "\ttry to cheat money using negative number." << endl; u.deposit(1000); !u.withdraw(10000, "123456789") ? cout << "Pass" : cout << "Fail"; cout << "\ttry to cheat money using loan which is not supported." << endl; cout << endl; } void runAllCases() { TestCase1(); TestCase2(); TestCase3(); } }; } #endif // TEST_H_
user.hpp
#include#ifndef USER_H_ #define USER_H_ namespace alipay { namespace Gender { enum Gender { Female = 0, Male = 1, Unknown = 2 }; } class User { std::string username; std::string password; std::string phone; Gender::Gender gender; long long int balance; inline bool verifyPasswordFormat(const std::string &password); inline bool verifyUsernameFormat(const std::string &username); inline bool verifyPhoneFormat(const std::string &phone); public: User() { this->gender = Gender::Unknown; this->balance = 0; } bool setUsername(const char *username); bool setPassword(const char *new_password, const char *old_password); bool setPhone(const char *new_phone); bool setGender(Gender::Gender gender); std::string getUsername(void); std::string getPhone(void); alipay::Gender::Gender getGender(void); // if passowrd is in correct, return -1 long long int getMoneyAmount(const char *password); bool deposit(long long int amount); bool withdraw(long long int amount, const char *password); }; } #endif // USER_H_
命名空間的問題.
user.cpp
#ifndef BITSET_H #define BITSET_H #include#include #include"user.hpp" #include"test.hpp" using namespace std; using namespace alipay; inline bool alipay::User::verifyPasswordFormat(const std::string &password) { bool isValid = true; int size = password.size(); if (size < 8 || size > 20) { isValid = false; } else { for (int i = 0; i < size; i++) { if ((password[i] >= '0' && password[i] <='9') || (password[i] >= 'a' && password[i] <='z') || (password[i] >= 'A' && password[i] <='Z')) { continue; } else { isValid = false; } } } return isValid; } inline bool alipay::User::verifyUsernameFormat(const std::string &username) { bool isValid = true; int size = username.size(); if (size < 6 || size > 20) { isValid = false; } else { for (int i = 0; i < size; i++) { if ((username[i] >= '0' && username[i] <='9') || (username[i] >= 'a' && username[i] <='z') || (username[i] >= 'A' && username[i] <='Z')) { continue; } else { isValid = false; } } } return isValid; } inline bool alipay::User::verifyPhoneFormat(const std::string &phone) { bool isValid = true; int size = phone.size(); if (size != 13) { isValid = false; } else { for (int i = 0; i < size; i++) { if (phone[i] < '0' || phone[i] >'9') { isValid = false; } } } return isValid; } bool alipay::User::setUsername(const char *newusername) { string temp = newusername; if (verifyUsernameFormat(temp)) { username = newusername; return true; } else { return false; } } bool alipay::User::setPassword(const char *new_password, const char *old_password) { string otemp = old_password; string ntemp = new_password; if (password == otemp) { if (verifyPasswordFormat(ntemp)) { password = ntemp; return true; } } else { return false; } } bool alipay::User::setPhone(const char *new_phone) { string temp = new_phone; if (verifyPhoneFormat(temp)) { phone = new_phone; return true; } else { return false; } } bool alipay::User::setGender(Gender::Gender newgender) { if (gender == Gender::Unknown && newgender == Gender::Unknown) { return false; } else { gender = newgender; return true; } } std::string alipay::User::getUsername(void) { return username; } std::string alipay::User::getPhone(void) { return phone; } alipay::Gender::Gender alipay::User::getGender(void) { return gender; } // if passowrd is in correct, return -1 long long int alipay::User::getMoneyAmount(const char *enterpassword) { string temp = enterpassword; if (temp == password) { return balance; } else { return -1; } } bool alipay::User::deposit(long long int amount) { if (amount > 0) { balance += amount; return true; } else { return false; } } bool alipay::User::withdraw(long long int amount, const char *enterpassword) { string temp = enterpassword; if (temp == password && amount > 0 && balance >= amount) { balance -= amount; return true; } else { return false; } } #endif
user.cpp
#include "user.hpp" #includestatic bool checkLetterAndNumberString(const std::string &str) { for (int i = 0; i < str.length(); i++) { if ((str[i] >= '0' && str[i] <= '9') || (str[i] >= 'a' && str[i] <= 'z') || (str[i] >= 'A' && str[i] <= 'Z')) { continue; } else { return false; } } return true; } bool alipay::User::verifyUsernameFormat(const std::string &username) { if (username.length() >= 6 && username.length() <= 20) { return checkLetterAndNumberString(username); } return false; } bool alipay::User::verifyPasswordFormat(const std::string &new_password) { if (new_password.length() >= 8 && new_password.length() <= 20) { return checkLetterAndNumberString(new_password); } return false; } bool alipay::User::verifyPhoneFormat(const std::string &phone) { if (phone.length() == 13) { for (int i = 0; i < phone.length(); i++) { if (phone[i] >= '0' && phone[i] <= '9') { continue; } else { return false; } } return true; } return false; } bool alipay::User::setUsername(const char *username) { std::string temp(username); if (this->verifyUsernameFormat(temp)) { this->username = temp; return true; } return false; } bool alipay::User::setPassword(const char *new_password, const char *old_password) { std::string old_password_s(old_password); if (old_password_s == this->password || this->password.length() == 0) { std::string new_password_s(new_password); if (verifyPasswordFormat(new_password_s)) { this->password = new_password_s; return true; } return false; } return false; } bool alipay::User::setPhone(const char *new_phone) { std::string new_phone_s(new_phone); if (this->verifyPhoneFormat(new_phone_s)) { // this->phone = new_phone; this->phone = new_phone_s; return true; } return false; } bool alipay::User::setGender(alipay::Gender::Gender gender) { if (this->gender == alipay::Gender::Unknown && gender != alipay::Gender::Unknown) { this->gender = gender; return true; } return false; } std::string alipay::User::getUsername(void) { return this->username; } std::string alipay::User::getPhone(void) { return this->phone; } alipay::Gender::Gender alipay::User::getGender(void) { return this->gender; } long long int alipay::User::getMoneyAmount(const char *password) { std::string password_s(password); if (this->password == password_s) { return this->balance; } return -1; } bool alipay::User::deposit(long long int amount) { if (amount > 0) { this->balance += amount; return true; } return false; } bool alipay::User::withdraw(long long int amount, const char *password) { std::string password_s(password); if (this->password == password_s) { if (amount > 0) { if (this->balance - amount >= 0) { this->balance -= amount; return true; } return false; } return false; } return false; }