[Classes and Objects]Alipay System 1 user

本文详细介绍了一个模拟支付宝用户模块的设计与实现过程,包括用户名、密码、电话号码的验证规则,性别设定,余额操作等功能。并通过一系列单元测试案例验证了模块的合法性和非法操作的处理。

Introduction

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.

Copy from 叶嘉祺 (已毕业多年老TA,大家怨念不要太深,如有问题欢迎邮件)讨论么么哒)

main.cpp
#include "user.hpp"
#include "test.hpp"
 
int main() {
  unittest::TEST t;
  t.runAllCases();
  return 0;
}
 
test.hpp
#ifndef TEST_H_
#define TEST_H_
#include "user.hpp"
#include <iostream>
#include <string>
 
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 <string>
 
#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
#include<iostream>
#include<string>
#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;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值