看到这样一样题,想想就简单的写了写自测一下,还是有很多收获。
需求:
1.模拟银行,客户关系封装类;
2.客户到银行办理业务需先排队;
3.银行根据队列处理业务,优选选择金卡客户;
4.办理建卡、存款、取钱、销户业务。
代码思路:
1.定义银行类,客户类,队列类;
2.思考现实实例,银行、队列只能有一个实例,客户可以有多个实例
3.理清类关系,银行依赖于队列决定客户,银行依赖客户数据处理业务,队列依赖客户排队
4.确定主导类为银行类,主要的业务逻辑在银行
Debug收获:
1.前向声明的类,只能用它的成员指针(之前没有注意这个问题)
2.对象传递尽量用指针,如果用返回值传递只能用堆内存
需要优化问题:
1.类的private封装,账户数据结构过于简单
2.银行客户账户数据存储用的是数组,可以用STL
3.银行账号,直接累加,可随机,要确保唯一
4.代码清晰易读,代码业务流程简化
#include <iostream> #include <stdio.h> #include <string> using namespace std; //常量宏 #define QUEUE_LONGTH_MAX 50 #define CARD_SUM_MAX 10000 #define GOLDEN_SUM_LIMIT 888 #define ILLEGAL_VALUE 0xffff //日志宏 #define log_info(...) do {\ printf("<%s %s> %s %s:%d INFO:",__DATE__, __TIME__,__FUNCTION__,__FILE__,__LINE__)&&\ printf(__VA_ARGS__)&&\ printf("\n");\ }while(0) //类声明 class CserviceQueue; class Cbank; class Ccustomer; class CserviceQueue; enum CARDTYPE { OrdinaryCard, //普卡 GoldenCard //金卡 }; //业务种类 enum SERVICE { registerCard, deposite, query, withdraw, cancelCard }; //银行账户 struct sbankCustomerAccount { int card_Number; int id_Customer; char* name; int moneySum; int cardType; }; //客户卡信息 struct sCard { int card_Number; int cardType; }; //排队队列节点 struct sRegisterNode { int num; Ccustomer *customer; sRegisterNode *next; }; //客户类 class Ccustomer { public: Ccustomer():queueNo(0),customerBankCard(NULL) { } //需要处理业务信息 void my_service(int id, char* name, int money, SERVICE ser) { customer_id = id; customer_name = name; customer_money = money; service = ser; } //delete掉自己的卡, customerBankCard在Cbank类中new void destoryCard() { delete customerBankCard; customerBankCard = NULL; } ~Ccustomer() { if(NULL!=customerBankCard) { delete customerBankCard; customerBankCard = NULL; } } int customer_id; char * customer_name; int customer_money; SERVICE service; sCard *customerBankCard; int queueNo; }; //排号队列类 class CserviceQueue { public: CserviceQueue():dealNumber(0),totalNumber(0) { head = tail = NULL; } //排队 int registerQueue(Ccustomer *customer) { if(totalNumber>QUEUE_LONGTH_MAX) { log_info("The queue is full ..."); return false; } p=new sRegisterNode; p->num=dealNumber; dealNumber++; totalNumber++; p->customer = customer; p->next=NULL; if (head==NULL) { head=tail=p; } else { tail->next=p; tail=p; } return p->num; } //读取队列数据,优选读金卡 Ccustomer* readQueue() { if(NULL != head) { pOrdinary = head; while(NULL != pOrdinary) { //客户还没有建卡 if (NULL != (pOrdinary->customer)->customerBankCard) { //读金卡 if (GoldenCard ==((pOrdinary->customer)->customerBankCard->cardType)) { return pOrdinary->customer; } } //如果没有金卡,依次读队列 pOrdinary = pOrdinary->next; } return head->customer; } return NULL; } //获取队列信息 void queueInfo() { pInfo = head; while(NULL != pInfo) { log_info("The left queue number: %d", pInfo->num); pInfo = pInfo->next; } log_info("Deal num amount %d, left num amount %d", dealNumber, totalNumber); } //删除队列节点 sRegisterNode *deleteData(int value) { sRegisterNode *p,*q; p = head; //队列为NULL if (head == NULL) { log_info("List is NULL"); return head; } //与传入值不等,继续遍历 while ((p->next!=NULL)&&(p->num!=value)) { q=p; p=p->next; } if (value==p->num) { if(head==p) { //头结点与传入值相等 head=p->next; } else //中间节点与传入值相等 q->next=p->next; totalNumber--; delete p; } else log_info("Number: %d is not in the queue", value); return head; } ~CserviceQueue() { while(NULL != head) { delete head; head = NULL; head = head->next; } } private: sRegisterNode *head,*tail,*p, *pOrdinary, *pInfo; int dealNumber;//当前处理号 int totalNumber;//当前队列总共号 }; //银行类 class Cbank { public: Cbank():card_amount(0),customer_card(NULL) { //初始化客户所有账号数组 memset(bank_card, ILLEGAL_VALUE, sizeof(bank_card)); } //处理业务 void dealService(Ccustomer* customer) { switch(customer->service) { //建卡业务 case registerCard: if(GOLDEN_SUM_LIMIT<(customer->customer_money)) { //钱多,建金卡 customer->customerBankCard=newCard(customer->customer_id, customer->customer_name, customer->customer_money, GoldenCard); } else { customer->customerBankCard=newCard(customer->customer_id, customer->customer_name, customer->customer_money, OrdinaryCard); } //customerInfoCheck(customer->customerBankCard->card_Number); break; //查询业务 case query: customerInfoCheck(customer->customerBankCard->card_Number); break; //存钱 case deposite: depositMoney(customer->customerBankCard->card_Number, customer->customer_money); //customerInfoCheck(customer->customerBankCard->card_Number); break; //取钱 case withdraw: withdrawMoney(customer->customerBankCard->card_Number, customer->customer_money); //customerInfoCheck(customer->customerBankCard->card_Number); break; //销卡 case cancelCard: cancelBankCard(customer->customerBankCard->card_Number, customer->customer_money); customer->destoryCard(); log_info("Bank card has been cancelled"); break; default: log_info("Wong service !"); break; } } //银行获取队列客户 Ccustomer* deal_queue_order(CserviceQueue *queue) { return queue->readQueue(); } //办卡 sCard* newCard(int id_Customer, char* name, int moneySum, int cardType) { bool flag = idCheck(id_Customer); if(flag) { //客户卡 customer_card = new sCard; customer_card->card_Number = card_Number; customer_card->cardType = cardType; //银行内部卡 bank_card[card_Number].card_Number = card_Number; bank_card[card_Number].id_Customer = id_Customer; bank_card[card_Number].name = name; bank_card[card_Number].moneySum = moneySum; bank_card[card_Number].cardType = cardType; card_Number++; card_amount++; return customer_card; } return false; } //存钱 void depositMoney(int card_Number,int moneySum) { bool flag = cardCheck(card_Number); if(flag) { bank_card[card_Number].moneySum += moneySum; } } //取钱 void withdrawMoney(int card_Number,int moneySum) { bool flag = cardCheck(card_Number); if(flag) { if(moneySum>bank_card[card_Number].moneySum) { log_info("Card: %d don't have enough money, just withdraw the money you have: %d", card_Number, bank_card[card_Number].moneySum); bank_card[card_Number].moneySum = 0; } else { bank_card[card_Number].moneySum -= moneySum; } } } //销卡 void cancelBankCard(int card_Number,int moneySum) { bank_card[card_Number].id_Customer = ILLEGAL_VALUE; bank_card[card_Number].card_Number = ILLEGAL_VALUE; bank_card[card_Number].name = NULL; bank_card[card_Number].moneySum = ILLEGAL_VALUE; bank_card[card_Number].cardType = ILLEGAL_VALUE; card_amount--; } //查询 void customerInfoCheck(int card_Number) { bool flag = cardCheck(card_Number); if(flag) { cout<<"==========================================================="<<endl; cout<<"customer "<<bank_card[card_Number].name <<" info: "<<endl; cout<<"card number: "<<bank_card[card_Number].card_Number<<endl; cout<<"id: "<<bank_card[card_Number].id_Customer<<endl; cout<<"money: "<<bank_card[card_Number].moneySum<<endl; cout<<"type: "<<bank_card[card_Number].cardType<<endl; cout<<"==========================================================="<<endl; } } //根据客户id检查是否已经有卡 bool idCheck(int id_Customer) { for(int i = 0;i<card_amount;i++) { if(id_Customer==bank_card[i].id_Customer) { log_info("Customer id: %d exist, don't need a card", id_Customer); return false; } } log_info("Customer id: %d can register a new card", id_Customer); return true; } //检查卡是否存在 bool cardCheck(int card_Number) { for(int i = 0;i<card_amount;i++) { if(card_Number==bank_card[i].card_Number) { return true; } } log_info("Card %d not exist, need register a new card", card_Number); return false; } //查询银行卡信息 void getBankInfo() { log_info("The max card number %d, there have %d customer",card_Number, card_amount); } ~Cbank() { } private: sbankCustomerAccount bank_card[CARD_SUM_MAX]; sCard *customer_card; int card_Number; int card_amount; }; int main() { //初始化银行,队列 Cbank *bank = new Cbank; CserviceQueue *queue = new CserviceQueue; //初始化2个客户,Lemon和Kevin Ccustomer *Lemon =new Ccustomer; Ccustomer *Kevin =new Ccustomer; //2人想办理的业务都是建卡 Lemon->my_service(888, "Lemon", 999, registerCard); Kevin->my_service(999,"Kevin", 500, registerCard); //排队,获取 号 Lemon->queueNo = queue->registerQueue(Lemon); Kevin->queueNo = queue->registerQueue(Kevin); //银行读队列找到客户,处理业务,删除已处理队列数据 Ccustomer *dealCustomer=bank->deal_queue_order(queue); bank->dealService(dealCustomer); queue->deleteData(dealCustomer->queueNo); //下一个处理 dealCustomer=bank->deal_queue_order(queue); bank->dealService(dealCustomer); queue->deleteData(dealCustomer->queueNo); //再次想办理业务,挂号 Lemon->my_service(888, "Lemon", 0, query); Kevin->my_service(999, "Kevin", 100, deposite); Kevin->queueNo = queue->registerQueue(Kevin); Lemon->queueNo = queue->registerQueue(Lemon); //注意噢,先挂号的是Kevin,但是先处理的是Lemon,因为他是金卡客户 dealCustomer=bank->deal_queue_order(queue); bank->dealService(dealCustomer); queue->deleteData(dealCustomer->queueNo); dealCustomer=bank->deal_queue_order(queue); bank->dealService(dealCustomer); queue->deleteData(dealCustomer->queueNo); //销卡 Kevin->my_service(999, "Kevin", 0, cancelCard); Kevin->queueNo = queue->registerQueue(Kevin); dealCustomer=bank->deal_queue_order(queue); bank->dealService(dealCustomer); queue->deleteData(dealCustomer->queueNo); //取钱 Lemon->my_service(888, "Lemon", 9999, withdraw); Lemon->queueNo = queue->registerQueue(Lemon); dealCustomer=bank->deal_queue_order(queue); bank->dealService(dealCustomer); queue->deleteData(dealCustomer->queueNo); //信息查询 queue->queueInfo(); bank->getBankInfo(); delete Lemon; delete Kevin; delete bank; delete queue; return 1; }