自测题1道

看到这样一样题,想想就简单的写了写自测一下,还是有很多收获。
需求:
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;
}


 

 

你可能感兴趣的:(自测题1道)