Contents
- 1. �칙
- 2. menu 추출 : 3번 �칙
- 3. while loop �서� 조건� - 1번
- 4. choice != 0 : 2번
- 5. MENU 부분� 대해서 : 2번
- 6. MENU ì„ íƒ� 부분과 ê´€ë ¨(choice >= 0 && choice <= 4), 잘못ë�œ 메뉴 ì„ íƒ� 골ë�¼ì£¼ê¸° : 1, 2번
- 7. Menu � 부분 - 1번 �칙
- 8. Vending Machine � 초기화 부분 - 4번 �칙
- 9. vending_machine::GetMoney () - 1, 3, 4번 �칙
- 10. temp_money - 4번
- 11. vending_machine::Buy () - 1,3,4
- 12. vending_machine::InsertDrink - 3,4
- 13. 중간 소스
1. ì›�ì¹™ ¶
다ì�Œê³¼ ê°™ì�€ 2ê°œì�˜ ì›�칙만 ì �용해서 ìˆ˜ì •í•´ë´¤ìŠµë‹ˆë‹¤.
- 명확하지 않는 변수/함수&메소드 �름� 대해 - �름� 다르게 바꿔준다. �는 무엇� 하기 위한 것�가� 입�, 함수/메소드 로 추출한다.
- 소위 magic number (ex : ë°°ì—´ì�˜ 범위를 ì„¤ì •í•˜ëŠ” 숫ìž�들) ë�¼ 불리는 것들ì—� 대해 - const 변수 ì„ ì–¸
- 긴 메소드 - 함수 & 메소드를 따로 추출. 즉, 하나ì�˜ 함수 ë‚´ì—�서 하는 ì�¼ë“¤ì�´ ë§Žë‹¤ê³ ìƒ�ê°�ë� 때.
- 중복 - 중복�는 부분� 대해 함수 & 메소드로 추출.
2. menu 추출 : 3번 ì›�ì¹™ ¶
~cpp
void printMenu () {
cout << "\n��기 입니다\n";
cout << "1.�� 넣는다\n";
cout << "2.물건� 산다\n";
cout << "3.ë�ˆì�„ ê±°ìˆ ëŸ¬ 받는다\n";
cout << "4.�료수를 채운다\n";
cout << "0.종료한다\n";
cout << "메뉴를 ì„ íƒ�하세요 : ";
}
3. while loop ì—�서ì�˜ ì¡°ê±´ì‹� - 1번 ¶
~cpp
bool isEndMenu (int choice) {
return choice != 0;
}
~cpp
while(isEndMenu (choice))
{
printMenu ();
cin >> choice;
.
.
4. choice != 0 : 2번 ¶
~cpp
enum {
MENU_END = 0,
};
~cpp
bool isEndMenu (int choice) {
return choice != MENU_END;
}
5. MENU 부분ì—� 대해서 : 2번 ¶
~cpp
enum {
MENU_END = 0,
MENU_GET_MONEY,
MENU_BUY,
MENU_TAKEBACK_MONEY,
MENU_INSERT_DRINK
};
~cpp
switch(choice)
{
case MENU_GET_MONEY:
VendingMachine.GetMoney();
break;
case MENU_BUY:
VendingMachine.Buy();
break;
case MENU_TAKEBACK_MONEY:
VendingMachine.TakeBackMoney();
break;
case MENU_INSERT_DRINK:
VendingMachine.InsertDrink();
break;
case MENU_END:
cout << "��기를 종료합니다!!\n\n";
break;
}
6. MENU ì„ íƒ� 부분과 ê´€ë ¨(choice >= 0 && choice <= 4), 잘못ë�œ 메뉴 ì„ íƒ� 골ë�¼ì£¼ê¸° : 1, 2번 ¶
~cpp
bool isValidMenu (int choice) {
return choice >= 0 && choice <= 4;
}
여기ì—� 2번ì�„ 다시 ì �용해주면
~cpp
bool isValidMenu (int choice) {
return choice >= MENU_END && choice <= MENU_INSERT_DRINK;
}
ê·¼ë�°.. 좀 명확해 ë³´ì�´ì§„ 않는군요. enum ì—�서 ì„¤ì •ë�œ 것ì�„ ìž¬ì •ì�˜í•´ì£¼ë©´~cpp
enum {
MENU_ENDCODE = 0,
MENU_START = 0,
MENU_GET_MONEY,
MENU_BUY,
MENU_TAKEBACK_MONEY,
MENU_INSERT_DRINK,
MENU_END = MENU_INSERT_DRINK
};
MENU_END 뜻ì�´ 달ë�¼ì¡Œìœ¼ë¯€ë¡œ, 앞ì—�서 MENU_END를 ì�¼ì—ˆë�˜ 다른 것들ë�„ ê³ ì¹©ë‹ˆë‹¤.~cpp case MENU_ENDCODE: cout << "ìž�íŒ�기를 종료합니다!!\n\n"; break; }
~cpp
bool isEndMenu (int choice) {
return choice != MENU_ENDCODE;
}
그러면, ~cpp isValidMenu 를 다ì�Œê³¼ ê°™ì�´ ê³ ì¹ ìˆ˜ 있습니다. (ì�¨ë†“ê³ ë³´ë‹ˆ 그리 맘ì—� 들진 않지만, ì�¼ë‹¨ ì�´ì •ë�„ë§Œ í•´ë‘�ê² ìŠµë‹ˆë‹¤. -_-;)~cpp
bool isValidMenu (int choice) {
return choice >= MENU_START && choice <= MENU_END;
}
7. Menu ì�˜ 부분 - 1번 ì›�ì¹™ ¶
~cpp case MENU_ENDCODE: VendingMachine.EndMachine(); break; } } else VendingMachine.PrintErrorMessage (); }
솔ì§�히 ì�´ë¶€ë¶„ì�´ 좋지 않ì�€ 것ì�´.. Vending Machine ë‚´ì—�서 UI 부분ì�´ 확실하게 추출ë�˜ì§€ 않았다는 ì �입니다. (ë§Œì�¼ Requirement ê°€ 변경ë�˜ì–´ì„œ, MFC 그래픽 ë²„ì „ìœ¼ë¡œ ë§Œë“ ë‹¤ë©´? ë””ìž�ì�¸ì�´ 잘 ë�œë‹¤ë©´, Vending Machine 쪽ì�˜ 코드ì�˜ ìˆ˜ì •ì�´ ê±°ì�˜ ì—†ì�´ UI 코드만 '추가' ë� ê²�니다. ì�´ëŠ” 기존 Vending Machine 코드쪽ì�˜ '변경'ì�„ ì�˜ë¯¸í•˜ì§€ 않습니다.)
하지만 ì�´ê±´ 추후ì—� Vending Machine ì—�서 메소드를 다른 í�´ëž˜ìФì—�게로 ì�´ì–‘시켜주면서 UI 부분과 ê´€ë ¨í•œ í�´ëž˜ìŠ¤ë¥¼ 추출해 낼 수 있ì�„ 것 ê°™ë‹¤ê³ ìƒ�ê°�합니다. 여기서는 추후ì—� 진행하ë�„ë¡� í•˜ê² ìŠµë‹ˆë‹¤.
ë””ìž�ì�¸ì�„ í• ë•Œì—� 보통 Input / Output ì�€ 요구사í•ì�´ ìž�주 바뀌므로 ì�¼ë‹¨ ë©”ì�¸ Vending Machine 코드가 작성ë�˜ê³ 난 ë’¤, Vending Machine ì�˜ ì�¸í„°íŽ˜ì�´ìФì—� 맞춰서 Input / Output 코드를 나중ì—� 작성하는 것ì�´ 좋습니다.
8. Vending Machine ì�˜ 초기화 부분 - 4번 ì›�ì¹™ ¶
~cpp const int DRINKNAME_MAXLENGTH = 255; const int TOTAL_DRINK_TYPE = 5;
~cpp
vending_machine::vending_machine()
{
money = temp_money = 0;
select_money = 1;
max_num = TOTAL_DRINK_TYPE;
char drinkNames[TOTAL_DRINK_TYPE][DRINKNAME_MAXLENGTH] = {"coke", "juice", "tea", "cofee", "milk"};
int price[TOTAL_DRINK_TYPE] = {400, 600, 500, 450, 350};
for (int i=0; i<max_num; i++) {
strcpy(s_drink[i].name , drinkNames[i]);
s_drink[i].price = price[i];
s_drink[i].amount = 10;
}
}
ì�¼ë‹¨ 여기까지ì�˜ 소스는 대강 ì�´ëŸ¬í•©ë‹ˆë‹¤. ì•„ì§�ì�€ ë� 그리 í�° 변화는 ëŠ�껴지지 않습니다.
(나머진 있다가 í•™êµ� ë�„착한 ë’¤ ë§ˆì €;)
(나머진 있다가 í•™êµ� ë�„착한 ë’¤ ë§ˆì €;)~cpp
#include <iostream>
using namespace std;
enum {
MENU_ENDCODE = 0,
MENU_START = 0,
MENU_GET_MONEY,
MENU_BUY,
MENU_TAKEBACK_MONEY,
MENU_INSERT_DRINK,
MENU_END = MENU_INSERT_DRINK
};
const int DRINKNAME_MAXLENGTH = 255;
const int TOTAL_DRINK_TYPE = 5;
class vending_machine
{
private:
int money;
int temp_money;
int select_money, select_drink, insert_amount;
struct drink
{
char name[DRINKNAME_MAXLENGTH];
int price, amount;
};
drink s_drink[5];
int max_num;
public:
vending_machine();
void GetMoney();
void Buy();
void TakeBackMoney();
void InsertDrink();
void EndMachine();
void PrintErrorMessage ();
};
vending_machine::vending_machine()
{
money = temp_money = 0;
select_money = 1;
max_num = TOTAL_DRINK_TYPE;
char drinkNames[TOTAL_DRINK_TYPE][DRINKNAME_MAXLENGTH] = {"coke", "juice", "tea", "cofee", "milk"};
int price[TOTAL_DRINK_TYPE] = {400, 600, 500, 450, 350};
for (int i=0; i<max_num; i++) {
strcpy(s_drink[i].name , drinkNames[i]);
s_drink[i].price = price[i];
s_drink[i].amount = 10;
}
}
void vending_machine::GetMoney()
{
cout << "�� 넣으세요. 10, 50, 100, 500, 1000만 가능 : ";
cin >> temp_money;
if(temp_money == 10 || temp_money == 50 || temp_money == 100 || temp_money == 500 || temp_money == 1000)
money = money + temp_money;
else
cout << "10, 50, 100, 500, 1000만 가능합니다. 다시 시작해주세요\n";
cout << money << "�� 넣었습니다\n";
}
void vending_machine::Buy()
{
cout << "�료수\t\t가격\t수량\n";
cout << "------------------------------------\n";
for(int i = 0 ; i < max_num ; i++)
cout << i + 1 << "." << s_drink[i].name << "\t\t" << s_drink[i].price << "\t" << s_drink[i].amount << "\n";
cout << "\n현재 " << money << "�� 있어요\n";
cout << "ì›�하는 ì�Œë£Œìˆ˜ë¥¼ ì„ íƒ�하세요 : ";
cin >> select_drink;
switch(select_drink)
{
case 1:
if((money - s_drink[select_drink - 1].price) >= 0 && s_drink[select_drink - 1].amount >= 1)
{
s_drink[select_drink - 1].amount--;
money = money - s_drink[select_drink - 1].price;
}
else
cout << "잔액� 부족하거나 수량� 부족해요\n";
break;
case 2:
if((money - s_drink[select_drink - 1].price) >= 0 && s_drink[select_drink - 1].amount >= 1)
{
s_drink[select_drink - 1].amount--;
money = money - s_drink[select_drink - 1].price;
}
else
cout << "잔액� 부족하거나 수량� 부족해요\n";
break;
case 3:
if((money - s_drink[select_drink - 1].price) >= 0 && s_drink[select_drink - 1].amount >= 1)
{
s_drink[select_drink - 1].amount--;
money = money - s_drink[select_drink - 1].price;
}
else
cout << "잔액� 부족하거나 수량� 부족해요\n";
break;
case 4:
if((money - s_drink[select_drink - 1].price) >= 0 && s_drink[select_drink - 1].amount >= 1)
{
s_drink[select_drink - 1].amount--;
money = money - s_drink[select_drink - 1].price;
}
else
cout << "잔액� 부족하거나 수량� 부족해요\n";
break;
case 5:
if((money - s_drink[select_drink - 1].price) >= 0 && s_drink[select_drink - 1].amount >= 1)
{
s_drink[select_drink - 1].amount--;
money = money - s_drink[select_drink - 1].price;
}
else
cout << "잔액� 부족하거나 수량� 부족해요\n";
break;
}
cout << money << "�� 남았어요\n";
}
void vending_machine::TakeBackMoney()
{
cout << "거스름ë�ˆ" << money << "ì›�ì�„ ë�Œë ¤ë“œë¦½ë‹ˆë‹¤\n";
money = 0;
}
void vending_machine::InsertDrink()
{
for(int i = 0 ; i < max_num ; i++)
cout << i + 1 << "." << s_drink[i].name << "\t" << s_drink[i].amount << "\n";
cout << "채우길 ì›�하는 ì�Œë£Œìˆ˜ë¥¼ ì„ íƒ�하세요 : ";
cin >> select_drink;
cout << "채우길 ì›�하는 ì�Œë£Œìˆ˜ 수량ì�„ ìž…ë ¥í•´ì£¼ì„¸ìš” : ";
cin >> insert_amount;
switch(select_drink)
{
case 1:
s_drink[select_drink - 1].amount += insert_amount;
break;
case 2:
s_drink[select_drink - 1].amount += insert_amount;
break;
case 3:
s_drink[select_drink - 1].amount += insert_amount;
break;
case 4:
s_drink[select_drink - 1].amount += insert_amount;
break;
case 5:
s_drink[select_drink - 1].amount += insert_amount;
break;
}
cout << "ì�Œë£Œìˆ˜ë¥¼ ì±„ì› ìŠµë‹ˆë‹¤\n";
for(i = 0 ; i < max_num ; i++)
cout << i + 1 << "." << s_drink[i].name << "\t" << s_drink[i].amount << "\n";
}
void vending_machine::EndMachine()
{
cout << "��기를 종료합니다!!\n\n";
}
void vending_machine::PrintErrorMessage ()
{
cout << "잘못ë�œ 메뉴 ì„ íƒ�입니다. 메뉴를 다시 ìž…ë ¥í•´ì£¼ì„¸ìš”\n";
}
void printMenu () {
cout << "\n��기 입니다\n";
cout << "1.�� 넣는다\n";
cout << "2.물건� 산다\n";
cout << "3.ë�ˆì�„ ê±°ìˆ ëŸ¬ 받는다\n";
cout << "4.�료수를 채운다\n";
cout << "0.종료한다\n";
cout << "메뉴를 ì„ íƒ�하세요 : ";
}
bool isEndMenu (int choice) {
return choice != MENU_ENDCODE;
}
bool isValidMenu (int choice) {
return choice >= MENU_START && choice <= MENU_END;
}
int main()
{
vending_machine VendingMachine;
int choice = -1;
while(isEndMenu (choice))
{
printMenu ();
cin >> choice;
if(isValidMenu (choice))
{
switch(choice)
{
case MENU_GET_MONEY:
VendingMachine.GetMoney();
break;
case MENU_BUY:
VendingMachine.Buy();
break;
case MENU_TAKEBACK_MONEY:
VendingMachine.TakeBackMoney();
break;
case MENU_INSERT_DRINK:
VendingMachine.InsertDrink();
break;
case MENU_ENDCODE:
VendingMachine.EndMachine();
break;
}
}
else
VendingMachine.PrintErrorMessage ();
}
return 0;
}
9. vending_machine::GetMoney () - 1, 3, 4번 ì›�ì¹™ ¶
'무엇ì�„ 하는가' ë�¼ê³ í• ë•Œ InsertMoney ë˜�는 InsertCoin ì�´ ë�” ì •í™•í•œ 표현ì�´ë�¼ ìƒ�ê°�ë�˜ì–´ì§‘니다. ê·¸ë¦¬ê³ , ì—시 하는 ì�¼ì—� 대해서 메소드로 추출함으로서 comment 를 ëŒ€ì‹ í• ìˆ˜ 있습니다.
~cpp
bool vending_machine::isValidMoney (int money) {
return (temp_money == 10 || temp_money == 50 || temp_money == 100 || temp_money == 500 || temp_money == 1000);
}
void vending_machine::InsertMoney()
{
cout << "�� 넣으세요. 10, 50, 100, 500, 1000만 가능 : ";
cin >> temp_money;
if (isValidMoney (temp_money)) {
money = money + temp_money;
}
else
cout << "10, 50, 100, 500, 1000만 가능합니다. 다시 시작해주세요\n";
cout << money << "�� 넣었습니다\n";
}
ê·¸ë¦¬ê³ , 메소드로 추출하면 좋ì�€ì �ì�´, 코드를 ê³ ì¹ ë¶€ë¶„ì�„ 메소드 내로 시야ì�˜ í�ì�„ 줄ì�¼ 수 있습니다. ìž‘ì�€ 메소드ë�¼ë�„ 추출해ë‘�ë©´ 나중ì—� 다시 메소드를 모으거나, 중복ì�„ ì—†ì• ê¸°ê°€ 편리합니다.
~cpp
bool vending_machine::isValidMoney (int money) {
int validMoneys[5] = {10, 50, 100, 500, 1000};
for (int i=0;i<5;i++) {
if (money == validMoney[i]) return true;
}
return false;
}
단, ì�´ëŸ¬í•œ 중복줄ì�´ê¸° & ì�¼ë°˜í™”는 중복ì�´ ë°œìƒ�ë�˜ì—ˆì�„때 (2 or 3 strike) 해주는 것ì�´ 쉽습니다. 처ì�Œë¶€í„° ëª¨ë“ ì¤‘ë³µë� 부분ì�„ 다 예측해 낼 수는 없습니다.
ì�´ ì�¼ë¶€í„° 시작, ë�” 극단ì �ì�¸ 예를 ë“ ë‹¤ë©´ 다ì�Œê³¼ ê°™ì�´ë�„ í• ìˆ˜ 있지만, ê¼ í• í•„ìš”ëŠ” 없습니다. (ê·¸ëŒ€ì‹ ì‹œë�„í•´ë³´ë©´ 재미있습니다) ì�¼ë‹¨ 넓게 넓게 보는 것ì�´ ë�” 좋기 때문ì—�.
~cpp
const int validMoney[5] = {10, 50, 100, 500, 1000};
void vending_machine::printInsertCoinMenu () {
cout << "�� 넣으세요. 10, 50, 100, 500, 1000만 가능 : ";
}
void vending_machine::printErrorInvalidCoinMessage () {
cout << "10, 50, 100, 500, 1000만 가능합니다. 다시 시작해주세요\n";
}
void vending_machine::printCurrentMoney () {
cout << money << "�� 넣었습니다\n";
}
bool vending_machine::isValidMoney (int money) {
for (int i=0;i<5;i++) {
if (money == validMoney[i]) return true;
}
return false;
}
void vending_machine::InsertMoney()
{
printInsertCoinMenu ();
cin >> temp_money;
if (isValidMoney (temp_money)) {
money = money + temp_money;
printCurrentMoney ();
}
else
printErrorInvalidCoinMessage ();
}
�것� 한번 � 중복� 줄�면
~cpp
void vending_machine::printInsertCoinMenu () {
cout << "�� 넣으세요. ";
for (int i=0;i<4;i++) {
cout << validMoneys[i] << ","
}
cout << valiMoneys[4] << "만 가능 : ";
}
10. temp_money - 4번 ¶
temp_money 가 하는 �� 보면 한가지 �만 합니다.
~cpp
void vending_machine::InsertMoney()
{
printInsertCoinMenu ();
cin >> temp_money;
if (isValidMoney (temp_money)) {
money = money + temp_money;
printCurrentMoney ();
}
else
printErrorInvalidCoinMessage ();
}
ì�´ ì�´ì™¸ì—” ì“°ì�´ì§€ 않지만, private 멤버로 있습니다. ì�´ëŸ¬í•œ ìž…ë ¥ì�„ 받기 위한 임시변수는 그냥 멤버ì—�서 ì—†ì• ì£¼ë©´ ë�©ë‹ˆë‹¤.~cpp
void vending_machine::InsertMoney()
{
int temp_money = 0;
printInsertCoinMenu ();
cin >> temp_money;
if (isValidMoney (temp_money)) {
money = money + temp_money;
printCurrentMoney ();
}
else
printErrorInvalidCoinMessage ();
}
11. vending_machine::Buy () - 1,3,4 ¶
1단계 - menu 부분 프린트 추출 & i -> drinkIndex 로 변경.
~cpp
void vending_machine::printBuyMenu () {
cout << "�료수\t\t가격\t수량\n";
cout << "------------------------------------\n";
for(int drinkIndex = 0 ; drinkIndex < max_num ; drinkIndex++)
cout << drinkIndex + 1 << "."
<< s_drink[drinkIndex].name << "\t\t"
<< s_drink[drinkIndex].price << "\t"
<< s_drink[drinkIndex].amount << "\n";
cout << "\n현재 " << money << "�� 있어요\n";
cout << "ì›�하는 ì�Œë£Œìˆ˜ë¥¼ ì„ íƒ�하세요 : ";
}
void vending_machine::Buy()
{
printBuyMenu ();
.
.
2단계 - switch & case ì�´ 부분ì—� 대해서 ì�´ë¯¸ ì�¼ë°˜í™” ê³µì‹�ì�„ 만들었ì�Œì—�ë�„ ë¶ˆêµ¬í•˜ê³ ë¶ˆí•„ìš”í•œ switch & case 문ì�´ 있습니다. ì�´ 부분ì—� 대해서는 ë§Žì�€ 코드를 줄ì�¼ 수 ìžˆê² ìŠµë‹ˆë‹¤.
~cpp
void vending_machine::Buy()
{
printBuyMenu ();
cin >> select_drink;
if((money - s_drink[select_drink-1].price) >= 0 && s_drink[select_drink-1].amount >= 1) {
s_drink[select_drink-1].amount--;
money = money - s_drink[select_drink-1].price;
}
else
cout << "잔액� 부족하거나 수량� 부족해요\n";
cout << money << "�� 남았어요\n";
}
ê·¸ë¦¬ê³ , select_drink-1 ì‹�으로 ì“´ 것ì�´ ë§Žì�€ë�°, ì�´ ì�´ìœ 는 아마 번호를 1,2,3,4 ... 로 ì°�기 위함ì�¼ 것입니다. ê·¸ë¦¬ê³ select_drink ë˜�한 vending_machine ì�˜ 멤버ì�¸ë�°, 특별히 하는 ì�¼ì�´ 없는 한 ì§€ì—변수로 ë‘�는것ì�´ 낫습니다.
12. vending_machine::InsertDrink - 3,4 ¶
~cpp
void vending_machine::InsertDrink()
{
int select_drink;
int insert_amount;
printCurrentDrinkStatus ();
cout << "채우길 ì›�하는 ì�Œë£Œìˆ˜ë¥¼ ì„ íƒ�하세요 : ";
cin >> select_drink;
cout << "채우길 ì›�하는 ì�Œë£Œìˆ˜ 수량ì�„ ìž…ë ¥í•´ì£¼ì„¸ìš” : ";
cin >> insert_amount;
if (select_drink-1 > 0 && select_drink-1 <=5)
s_drink[select_drink-1].amount += insert_amount;
cout << "ì�Œë£Œìˆ˜ë¥¼ ì±„ì› ìŠµë‹ˆë‹¤\n";
printCurrentDrinkStatus ();
}
13. 중간 소스 ¶
~cpp
#include <iostream>
using namespace std;
enum {
MENU_ENDCODE = 0,
MENU_START = 0,
MENU_GET_MONEY,
MENU_BUY,
MENU_TAKEBACK_MONEY,
MENU_INSERT_DRINK,
MENU_END = MENU_INSERT_DRINK
};
const int DRINKNAME_MAXLENGTH = 255;
const int TOTAL_DRINK_TYPE = 5;
const int validMoney[5] = {10, 50, 100, 500, 1000};
class vending_machine
{
private:
int money;
struct drink
{
char name[DRINKNAME_MAXLENGTH];
int price, amount;
};
drink s_drink[TOTAL_DRINK_TYPE];
int max_num;
public:
vending_machine();
void InsertMoney();
void Buy();
void TakeBackMoney();
void InsertDrink();
void EndMachine();
bool isValidMoney (int money);
void PrintErrorMessage ();
void PrintErrorInvalidCoinMessage ();
void PrintInsertCoinMenu();
void PrintCurrentMoney ();
void PrintBuyMenu ();
void PrintCurrentDrinkStatus ();
};
vending_machine::vending_machine()
{
money = 0;
max_num = TOTAL_DRINK_TYPE;
char drinkNames[TOTAL_DRINK_TYPE][DRINKNAME_MAXLENGTH] = {"coke", "juice", "tea", "cofee", "milk"};
int price[TOTAL_DRINK_TYPE] = {400, 600, 500, 450, 350};
for (int i=0; i<max_num; i++) {
strcpy(s_drink[i].name , drinkNames[i]);
s_drink[i].price = price[i];
s_drink[i].amount = 10;
}
}
void vending_machine::PrintInsertCoinMenu () {
cout << "�� 넣으세요. ";
for (int i=0;i<4;i++)
cout << validMoney[i] << "," ;
cout << validMoney[4] << "만 가능 : ";
}
void vending_machine::PrintErrorInvalidCoinMessage () {
cout << "�� 넣으세요. ";
for (int i=0;i<4;i++)
cout << validMoney[i] << ",";
cout << validMoney[4] << "만 가능합니다. 다시 시작해주세요\n";
}
void vending_machine::PrintCurrentMoney () {
cout << money << "�� 넣었습니다\n";
}
bool vending_machine::isValidMoney (int money) {
for (int i=0;i<5;i++)
if (money == validMoney[i]) return true;
return false;
}
void vending_machine::InsertMoney()
{
int temp_money = 0;
PrintInsertCoinMenu ();
cin >> temp_money;
if (isValidMoney (temp_money)) {
money = money + temp_money;
PrintCurrentMoney ();
}
else
PrintErrorInvalidCoinMessage ();
}
void vending_machine::PrintBuyMenu () {
cout << "�료수\t\t가격\t수량\n";
cout << "------------------------------------\n";
for(int drinkIndex = 0 ; drinkIndex < max_num ; drinkIndex++)
cout << drinkIndex + 1 << "."
<< s_drink[drinkIndex].name << "\t\t"
<< s_drink[drinkIndex].price << "\t"
<< s_drink[drinkIndex].amount << "\n";
cout << "\n현재 " << money << "�� 있어요\n";
cout << "ì›�하는 ì�Œë£Œìˆ˜ë¥¼ ì„ íƒ�하세요 : ";
}
void vending_machine::Buy()
{
PrintBuyMenu ();
int select_drink;
cin >> select_drink;
if((money - s_drink[select_drink-1].price) >= 0 && s_drink[select_drink-1].amount >= 1) {
s_drink[select_drink-1].amount--;
money = money - s_drink[select_drink-1].price;
}
else
cout << "잔액� 부족하거나 수량� 부족해요\n";
cout << money << "�� 남았어요\n";
}
void vending_machine::TakeBackMoney()
{
cout << "거스름ë�ˆ" << money << "ì›�ì�„ ë�Œë ¤ë“œë¦½ë‹ˆë‹¤\n";
money = 0;
}
void vending_machine::PrintCurrentDrinkStatus () {
for(int drinkIndex = 0 ; drinkIndex < max_num ; drinkIndex++)
cout << drinkIndex + 1 << "."
<< s_drink[drinkIndex].name << "\t"
<< s_drink[drinkIndex].amount << "\n";
}
void vending_machine::InsertDrink()
{
int select_drink;
int insert_amount;
PrintCurrentDrinkStatus ();
cout << "채우길 ì›�하는 ì�Œë£Œìˆ˜ë¥¼ ì„ íƒ�하세요 : ";
cin >> select_drink;
cout << "채우길 ì›�하는 ì�Œë£Œìˆ˜ 수량ì�„ ìž…ë ¥í•´ì£¼ì„¸ìš” : ";
cin >> insert_amount;
if (select_drink-1 > 0 && select_drink-1 <=5)
s_drink[select_drink-1].amount += insert_amount;
cout << "ì�Œë£Œìˆ˜ë¥¼ ì±„ì› ìŠµë‹ˆë‹¤\n";
PrintCurrentDrinkStatus ();
}
void vending_machine::EndMachine()
{
cout << "��기를 종료합니다!!\n\n";
}
void vending_machine::PrintErrorMessage ()
{
cout << "잘못ë�œ 메뉴 ì„ íƒ�입니다. 메뉴를 다시 ìž…ë ¥í•´ì£¼ì„¸ìš”\n";
}
void PrintMenu () {
cout << "\n��기 입니다\n";
cout << "1.�� 넣는다\n";
cout << "2.물건� 산다\n";
cout << "3.ë�ˆì�„ ê±°ìˆ ëŸ¬ 받는다\n";
cout << "4.�료수를 채운다\n";
cout << "0.종료한다\n";
cout << "메뉴를 ì„ íƒ�하세요 : ";
}
bool isEndMenu (int choice) {
return choice != MENU_ENDCODE;
}
bool isValidMenu (int choice) {
return choice >= MENU_START && choice <= MENU_END;
}
void vending_machine::Run () {
int choice = -1;
while(isEndMenu (choice))
{
PrintMenu ();
cin >> choice;
if(isValidMenu (choice))
{
switch(choice)
{
case MENU_GET_MONEY:
InsertMoney();
break;
case MENU_BUY:
Buy();
break;
case MENU_TAKEBACK_MONEY:
TakeBackMoney();
break;
case MENU_INSERT_DRINK:
InsertDrink();
break;
case MENU_ENDCODE:
EndMachine();
break;
}
}
else
PrintErrorMessage ();
}
}
int main()
{
vending_machine VendingMachine;
VendingMachine.Run ();
return 0;
}
ì�´ì¯¤ì—�서 ë¬¸ì œì � - vending_machine ì�´ ì™„ì „ížˆ God í�´ëž˜ìŠ¤ìž…ë‹ˆë‹¤. ì™„ì „ížˆ ì�´ 프로그램 ìž�ì²´ê°€ vending_machine ê°�체와 ë�™ê¸‰ì�´ ë�˜ì–´ë²„ë¦¬ì£ .
ìž…ì¶œë ¥ë¶€ë¶„ê³¼ Vending Machine ìž�ì²´ì�˜ 분리
~cpp
#ifndef _VENDINGMACHINE_H_
#define _VENDINGMACHINE_H_
#include <iostream>
#include <string>
#include <vector>
#include <map>
#include <algorithm>
using namespace std;
class Drink
{
public:
string name;
int price;
int amount;
Drink (string name, int price, int amount) {
this->name = name;
this->price = price;
this->amount = amount;
}
};
class VendingMachine
{
public:
int money;
vector <Drink*> drinks;
vector <int> validMoney;
VendingMachine() {
this->money = 0;
string drinkNames[] = {"coke", "juice", "tea", "cofee", "milk"};
int price[] = {400, 600, 500, 450, 350};
int defaultAmount = 10;
int TOTAL_DRINK_TYPE = 5;
int validMoneyList[] = {10, 50, 100, 500, 1000};
int TOTAL_MONEY_TYPE = 5;
Drink* drink;
for (int drinkIndex=0; drinkIndex<TOTAL_DRINK_TYPE; drinkIndex++) {
drink = new Drink(drinkNames[drinkIndex], price[drinkIndex], defaultAmount);
registerDrink (drink);
}
for (int moneyIndex=0; moneyIndex<TOTAL_MONEY_TYPE; moneyIndex++) {
registerMoneyType (validMoneyList[moneyIndex]);
}
}
~VendingMachine () {
for (int i=0; i< drinks.size(); i++) {
delete drinks[i];
}
drinks.clear();
}
void registerMoneyType (int moneyType) {
validMoney.push_back(moneyType);
}
bool isValidDrinkIndex (int drinkIndex) {
return (drinkIndex>=0 && drinkIndex <5);
}
void chargeDrink (int drinkIndex, int amount) {
drinks[drinkIndex]->amount += amount;
}
vector<int> getValidMoneyTypes(void) {
return this->validMoney;
}
bool VendingMachine::isBuyable(int drinkId) {
return ((getMoney() - drinks[drinkId]->price >= 0) &&
(drinks[drinkId]->amount >= 1));
}
vector<Drink*> getRegisteredDrinks () {
return this->drinks;
}
void VendingMachine::buy (int drinkId) {
drinks[drinkId]->amount--;
chargeMoney (drinks[drinkId]->price);
}
void registerDrink (Drink* drink) {
drinks.push_back(drink);
}
bool isValidMoneyType (int money) {
for (int i=0; i<validMoney.size();i++) {
if (validMoney[i] == money)
return true;
}
return false;
}
int takeBackMoney()
{
int takeBackMoney = this->money;
this->money = 0;
return takeBackMoney;
}
void insertMoney (int money) {
this->money += money;
}
void chargeMoney (int drinkPrice) {
this->money -= drinkPrice;
}
int getMoney () {
return money;
}
};
#endif
main.cpp
#include "VendingMachine.h"
#include <iostream>
#include <map>
using namespace std;
enum {
MENU_ENDCODE = 0,
MENU_START = 0,
MENU_GET_MONEY,
MENU_BUY,
MENU_TAKEBACK_MONEY,
MENU_INSERT_DRINK,
MENU_END = MENU_INSERT_DRINK
};
typedef void(*Func)(VendingMachine&);
void InsertMoney(VendingMachine& vendingMachine);
void Buy(VendingMachine& vendingMachine);
void TakeBackMoneyMenu(VendingMachine& vendingMachine);
void InsertDrink(VendingMachine& vendingMachine);
void EndMachine(VendingMachine& vendingMachine);
void PrintErrorMessage ();
void PrintErrorInvalidCoinMessage (VendingMachine& vendingMachine);
void PrintInsertCoinMenu();
void PrintCurrentMoney (int money);
void PrintBuyMenu (int money);
void PrintCurrentDrinkStatus ();
void PrintErrorInvalidCoinMessage (VendingMachine& vendingMachine) {
cout << "�� 넣으세요. ";
vector<int> validMoney = vendingMachine.getValidMoneyTypes();
for (int i=0;i<validMoney.size()-1;i++)
cout << validMoney[i] << ",";
cout << validMoney[i] << "만 가능합니다. 다시 시작해주세요\n";
}
void PrintCurrentMoney (int money) {
cout << money << "�� 넣었습니다\n";
}
void PrintBuyMenu (VendingMachine& vendingMachine) {
cout << "�료수\t\t가격\t수량\n";
cout << "------------------------------------\n";
vector <Drink*> drinks = vendingMachine.getRegisteredDrinks();
for(int drinkIndex = 0 ; drinkIndex < drinks.size() ; drinkIndex++) {
cout << drinkIndex << "."
<< drinks[drinkIndex]->name << "\t\t"
<< drinks[drinkIndex]->price << "\t"
<< drinks[drinkIndex]->amount << "\n";
}
PrintCurrentMoney (vendingMachine.getMoney());
cout << "ì›�하는 ì�Œë£Œìˆ˜ë¥¼ ì„ íƒ�하세요 : ";
}
void Buy(VendingMachine& vendingMachine)
{
PrintBuyMenu (vendingMachine);
int drinkId;
cin >> drinkId;
if(vendingMachine.isBuyable(drinkId)) {
vendingMachine.buy (drinkId);
cout << vendingMachine.getMoney() << "�� 남았어요\n";
}
else
cout << "잔액� 부족하거나 수량� 부족해요\n";
}
void TakeBackMoney (VendingMachine& vendingMachine) {
int takeBackMoney = vendingMachine.takeBackMoney ();
cout << "거스름ë�ˆ" << takeBackMoney << "ì›�ì�„ ë�Œë ¤ë“œë¦½ë‹ˆë‹¤\n";
}
void PrintCurrentDrinkStatus (VendingMachine& vendingMachine) {
vector<Drink*> drinks = vendingMachine.getRegisteredDrinks();
for(int drinkIndex = 0 ; drinkIndex < drinks.size() ; drinkIndex++)
cout << drinkIndex << "."
<< drinks[drinkIndex]->name << "\t"
<< drinks[drinkIndex]->amount << "\n";
}
void PrintErrorMessage ()
{
cout << "잘못ë�œ 메뉴 ì„ íƒ�입니다. 메뉴를 다시 ìž…ë ¥í•´ì£¼ì„¸ìš”\n";
}
void InsertMoney(VendingMachine& vendingMachine)
{
int money = 0;
cout << "�� 넣으세요. ";
vector<int> validMoney = vendingMachine.getValidMoneyTypes();
for (int i=0;i<validMoney.size()-1;i++)
cout << validMoney[i] << "," ;
cout << validMoney[i] << "만 가능 : ";
cin >> money;
if (vendingMachine.isValidMoneyType (money)) {
vendingMachine.insertMoney (money);
PrintCurrentMoney (vendingMachine.getMoney ());
}
else
PrintErrorInvalidCoinMessage (vendingMachine);
}
void InsertDrink(VendingMachine& vendingMachine)
{
int selectDrink;
int insertAmount;
PrintCurrentDrinkStatus (vendingMachine);
cout << "채우길 ì›�하는 ì�Œë£Œìˆ˜ë¥¼ ì„ íƒ�하세요 : ";
cin >> selectDrink;
cout << "채우길 ì›�하는 ì�Œë£Œìˆ˜ 수량ì�„ ìž…ë ¥í•´ì£¼ì„¸ìš” : ";
cin >> insertAmount;
if (vendingMachine.isValidDrinkIndex (selectDrink)) {
vendingMachine.chargeDrink (selectDrink, insertAmount);
cout << "ì�Œë£Œìˆ˜ë¥¼ ì±„ì› ìŠµë‹ˆë‹¤\n";
}
PrintCurrentDrinkStatus (vendingMachine);
}
void EndMachine(VendingMachine& vendingMachine)
{
cout << "��기를 종료합니다!!\n\n";
}
bool isEndMenu (int choice) {
return choice != MENU_ENDCODE;
}
bool isValidMenu (int choice) {
return choice >= MENU_START && choice <= MENU_END;
}
int InputMainMenu () {
int choice = -1;
cout << "\n��기 입니다\n"
<< "1.�� 넣는다\n"
<< "2.물건� 산다\n"
<< "3.�� 거슬러 받는다\n"
<< "4.�료수를 채운다\n"
<< "0.종료한다\n"
<< "메뉴를 ì„ íƒ�하세요 : ";
cin >> choice;
return choice;
}
int main()
{
VendingMachine vendingMachine;
int choice = -1;
int menuList[] = { MENU_GET_MONEY, MENU_BUY, MENU_TAKEBACK_MONEY, MENU_INSERT_DRINK, MENU_ENDCODE};
Func funcList[] = { InsertMoney, Buy, TakeBackMoney, InsertDrink, EndMachine };
map<int, Func> menuTable;
for (int menuIndex=0; menuIndex<5; menuIndex++) {
menuTable[menuList[menuIndex]] = funcList[menuIndex];
}
while (isEndMenu (choice)) {
choice = InputMainMenu ();
if (isValidMenu (choice)) {
(*menuTable[choice])(vendingMachine);
}
else
PrintErrorMessage ();
}
return 0;
}










