작성자의 페이지

02 장재니 Genie

프로그램 설계


클래스 나누기

  • 먼저 자판기(VendingMachine)이 필요할 것이고,
  • 주문하는 사람(Man)도 있어야 할 것이다..
  • 자판기는 사용자 인터페이스를 구현하는데 사용하고, 사람이 주문할 음료(Drink)를 따로 분류하자..
  • 그러면 주문을 할 때 돈이 필요하니까 돈을 세는 계수기 비슷한 것(CoinCounter)도 필요할 것 같다..^^
이정도면 클래스를 나누는 것은 끝난 것 같으니깐 각각의 객체(클래스)에 필요한 역할을 나누어보자..^^

역할 분담하기

  • 먼저 자판기의 역할을 보자..... 자판기는 먼저 메뉴를 사람에게 보여줄 수 있어야 될꺼얌...
  • 그리고 사람은 메뉴를 보고 각 메뉴에 알맞은 명령을 내릴 수 있어야 할것이고...
  • 음료가 해야할 일은 뭐가 있을까?

    먼저 자신의 상태(품목,가격,수량)을 기억하고 사람에게 보여줄 수 있어야겠지...

    그리고 사람이 주문을 했을 때 주문받은 상품의 가격에 비해 잔액이 충분한지 확인 하는 것 하구..... / 계수기

    또 주문받은 상품이 남아있는지도 체크해야 될꺼야!!^^

    이 두가지 조건에 만족할 때에는 주문한 상품을 내줄 수 있어야 하겠고, 이 때 상품의 수량을 갱신해야겠지!^^

  • 흠.. 그리고 계수기의 역할을 한번 볼까? 이녀석은 먼저 잔액을 기억해서 보여주어야 할 것이고..

    사람이 투입한 돈이 형식에 맞는지(10,50,100,500,1000원) 확인해서 잔액을 늘려주어야 할 것이고,

    사람이 돈의 반환을 요구하면 돈을 꺼내주고 잔액을 초기화 할 수 있어야 하겠지?^^

    아!! 그리고 주문한 음료의 가격에 따라 금액을 지불해주는 역할도 있어야겠군!^^

가만있자.. 이거면 역할 분담은 대충 끝난 셈인가? 그럼 한번 코딩을 해볼까?*

소스

~cpp 
#include <iostream>
#include <cstring>
using namespace std;

int selection, num;

class Man{
public:
	void select(){
		selection = 0;
		while (selection < 1 || selection > num){
			cout << ">> ";
			cin >> selection;
			if (selection < 1 || selection > num)
				cout << "잘못 입력하셨습니다. n";
		}
	};
};

class CoinCounter{
public:
	int remainders, coin;
	void resetCoins(){
		remainders = 0;
	};
	void showRemainders(){
		cout << "REMAINDERS : " << remainders << endl;
	};
	void insertCoins(){
		cout << "돈을 넣으세요.n 1. 10원 n 2. 50원 n 3. 100원 n 4. 500원 n 5. 1000원 n>> ";
		cin >> coin;
		if (coin == 1)			coin = 10;
		else if (coin == 2)		coin = 50;
		else if (coin == 3)		coin = 100;
		else if (coin == 4)		coin = 500;
		else if (coin == 5)		coin = 1000;
		else coin = 0;
		remainders += coin;
		cout << coin <<"원을 넣으셨습니다. n잔액은 " << remainders << "입니다.n";
	};
	void pay(int used){
		cout << used << "원을 사용하셨습니다.n";
		remainders -= used;
	};
};

class VendingMachine{
public:
	void showMenu(){
	num = 4;
	cout << "MAIN MENU n 1. INSERT COIN n 2. BUY n 3. RETURN THE REMAINDERS n 4. EXIT n";
	};
};

class Drink{
public:
	struct drinks{
		char name[10];
		int price;
		int quantity;
	};
	drinks detail[3];
	Drink(){
		strcpy(detail[0].name, "사이다");
		strcpy(detail[1].name, "콜라");
		strcpy(detail[2].name, "2% 부족");
		detail[0].price = 500;
		detail[1].price = 400;
		detail[2].price = 600;
		for (int i = 0 ; i < 3 ; i++)
			detail[i].quantity = 10;
	};
	void showDetails(){
		num = 3;
		cout << " 상품명t 가격t 수량n";
		for (int i = 0 ; i < 3; i++)
			cout << i+1 << ". " << detail[i].name << "t"
				<< detail[i].price << "t"
				<< detail[i].quantity << endl;
	};
	int buy(int remainders){
		if (remainders >= detail[selection - 1].price && detail[selection - 1].quantity != 0){
			cout << detail[selection - 1].name << "을 선택하셨습니다.n";
			detail[selection - 1].quantity--;
			return detail[selection - 1].price;
		}
		else if (detail[selection - 1].price > remainders)
			cout << "잔액이 부족합니다.n";
		else if (detail[selection - 1].quantity == 0)
			cout << "매진되었습니다. 다른 상품을 골라주십시오.n";
		return 0;
	};
};

int main(){
	Man man;
	CoinCounter coin_counter;
	VendingMachine vending_machine;
	Drink drink;
	int usedmoney;
	coin_counter.resetCoins();
	while(selection != 4)
	{
		vending_machine.showMenu();
		coin_counter.showRemainders();
		man.select();
		if (selection == 1)
			coin_counter.insertCoins();
		else if (selection == 2){
			drink.showDetails();
			man.select();
			usedmoney = drink.buy(coin_counter.remainders);
			coin_counter.pay(usedmoney);
		}
		else if (selection == 3){
			cout << "잔액을 반환합니다.n";
			coin_counter.resetCoins();
		}
		else if (selection == 4)
			break;
		else cout << "잘못 입력하셨습니다.n";
		system("pause");
		system("cls");
	};
	return 0;
}

만들고나서..

  • 클래스를 너무 많이 만들어서 괜히 복잡해졌다는 재동이 형의 지적을 받았습니다.

    아직 클래스 사용법도 제대로 모르는지라 서툴기도 하고.. 결론은 역시 공부해야할 것이 많다는 것...^^
  • 지금까지는 안했었지만 대충의 구조는 말해두는 게 좋을 것 같습니다...^^

    배우는 게 많아질수록 코드가 조금씩 복잡해져서 나중에는 못 알아볼지도 모르는 생각이 드는군요..^^
  • 이번엔 프로그램 설계를 한글로 했지만 영어로 해보고 싶은 욕심이 생기네엽..^^

    (그럼 공부할 영역이 하나 더 늘어나는건가...^^∂)
    클래스 수가 많아서 복잡해진건 아닌듯(모 VendingMachine 의 경우 Requirement 변경에 따라 클래스갯수가 10개 이상이 되기도 함; 클래스 수가 중요하다기보다도 최종 완료된 소스가 얼마나 명료해졌느냐가 복잡도를 결정하리라 생각). 단, 역할 분담할때 각 클래스별 역할이 명료한지 신경을 쓰는것이 좋겠다. CoinCounter 의 경우 VendingMachine 안에 멤버로 있어도 좋을듯. CRC 세션을 할때 클래스들이 각각 따로 존재하는 것 같지만, 실제론 그 클래스들이 서로를 포함하고 있기도 하거든. 또는 해당 기능을 구현하기 위해 다른 클래스들과 협동하기도 하고 (Collaboration. 실제 구현시엔 다른 클래스의 메소드들을 호출해서 구현한다던지 식임). 역할분담을 하고 난 다음 모의 시나리오를 만든뒤 코딩해나갔다면 어떠했을까 하는 생각도 해본다. 이 경우에는 UnitTest 를 작성하는게 좋겠지. UnitTest 작성 & 진행에 대해선 ScheduledWalk/석천 의 중반부분이랑 UnitTest 참조.--1002
----
see also FifteenSecondsRule
----
CppStudy_2002_2 VendingMachine

Retrieved from http://wiki.zeropage.org/wiki.php/VendingMachine/재니
last modified 2021-02-07 05:28:21