본문 바로가기
Project

Team1) 자판기 프로그램

by code_learner 2022. 1. 11.

[기간]

22.01.04(화)~22.01.09(일)

 

 

[프로그램 흐름도]

*회의 때는 관리자모드에서 상품추가 이야기가 나왔지만 구현하지 못했다

 

 

 

 

[프로젝트 구조]

1. Drink 클래스를 만들고 각 음료종류 클래스가 상속받는다

2. Pay클래스는 객체생성시 돈을 입력받고, 결제를 진행한다.

3. Admin클래스는 pw를 가지고 있고, 재고 추가 메서드를 가지고 있다.

 

 

 

 

[코드]

 

-Pay클래스

class Pay {//결제 클래스
	private int money;//가지고 있는 돈을 저장

	public int getMoney() {
		return money;
	}

	public void setMoney(int money) {
		this.money = money;
	}

	public Pay(int money) {//생성자로 돈 투입
		this.money = money;
	}

	void pay(Drink drink, int orders) { //결제 매개변수로 마실음료를 입력받고, 사용자가 요구하는 음료갯수를 입력받는다.
		if(orders > drink.getCnt()) { //음료수 재고 없을시(주문수량>재고)
			System.out.println("재고가 부족합니다.");
		}else{//음료 재고가 있다면
			if(money < drink.getPrice()*orders) { //지불해야할 금액이 초기금액 초과시(초기돈<가격)
				System.out.println("잔액이 부족합니다.");
			}else {//지불해야할금액완료
				money -= (drink.getPrice() * orders);//구매자의 돈에서 음료*입력개수 빼기
				drink.setCnt(drink.getCnt() - orders);//재고-입력개수 빼기
				
				System.out.println("주문하신 음료"+drink.getName()+"가 결제되었습니다.");
				System.out.println("남은 잔액은"+money+"원 남았습니다.");
			}
		}
	}
}

 

-admin클래스

class Admin {//관리자 클래스

	private int pw;//패스워드변수
	public Admin(int pw) {
		this.pw = pw;
	}

	boolean checkPW(int pw){//관리자 번호 확인 메서드
		//입력값과 관리자 번호가 같다면 true를 리턴한다
		if(this.pw==pw) {
			return true;
		}else {
			return false;
		}
	}

	void plusCnt(Drink drink, int cnt) {//재고 추가 메서드
		//추가하고자 하는 drink객체와 더할 값을 인자로 받는다
		drink.setCnt(drink.getCnt() + cnt);		
	}
}

 

-Drink클래스와 상속

class Drink{//자판기 음료클래스
	private String name;//음료수 이름
	private int cnt;//음료 재고	private static int pkNum;
	private static int pkNum=1001;//PK저장값
	private int pk;//고유 PK값
	private int price; //음료수 값

	public String getName() {		
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public int getCnt() {
		return cnt;
	}

	public void setCnt(int cnt) {
		this.cnt = cnt;
	}

	public static int getPkNum() {
		return pkNum;
	}
	
	public static void setPkNum(int pkNum) {
		Drink.pkNum = pkNum;
	}

	public int getPk() {
		return pk;
	}

	public void setPk(int pk) {
		this.pk = pk;
	}

	public int getPrice() {
		return price;
	}

	public void setPrice(int price) {
		this.price = price;
	}

	Drink(String name,int cnt,int price) {//음료생성자
		this.name=name;
		this.cnt=cnt;
		this.price=price;
		this.pk=pkNum;
		//각 음료마다 고유 PK값 부여후
		pkNum++;
		//pkNum 1씩 증가   
	}
}

class Coffee extends Drink{//커피클래스
	Coffee(String name, int cnt, int price) {
		super(name, cnt, price);
	}

	@Override   
	public String toString() {
		return getName() + " 수량:" + getCnt() + " 가격:"+getPrice()+"원"; //커피이름,커피수량,커피가격
	}
}

class Juice extends Drink{//주스클래스
	Juice(String name, int cnt, int price) {
		super(name, cnt, price);
	}

	@Override
	public String toString() {
		return getName() + " 수량:" + getCnt() + " 가격:"+getPrice()+"원";
	}
}

class Soda extends Drink{//탄산클래스
	Soda(String name, int cnt, int price) {
		super(name, cnt, price);
	}

	@Override
	public String toString() {
		return getName() + " 수량:" + getCnt() + " 가격:"+getPrice()+"원";
	}
}

class Ion extends Drink{//이온음료클래스
	Ion(String name, int cnt, int price) {
		super(name, cnt, price);
	}

	@Override
	public String toString() {
		return getName() + " 수량:" + getCnt() + " 가격:"+getPrice()+"원";
	}
}

 

-메인클래스

1. 메인메서드

    소비자와 관리자를 따로 분리하여 메서드화 하였다.

	public static void main(String[] args) {

		Scanner sc=new Scanner(System.in);
		Admin ad=new Admin(1234);//관리자객체 생성
		
		int num=7;//음료개수
		Drink[] drink=new Drink[num];//음료클래스 배열

		drink[0]=new Coffee("아메리카노", 10,1500);
		drink[1]=new Coffee("라떼 ", 10,1600);
		drink[2]=new Ion("파워에이드", 10,2000);
		drink[3]=new Juice("오렌지주스", 10,1400);
		drink[4]=new Juice("포도주스 ", 10,1400);
		drink[5]=new Soda("콜라 ", 10,2200);
		drink[6]=new Soda("사이다 ", 10,2000);

		while(true) {
			System.out.println("1.소비자 2.관리자 3.종료"); 
			int a = sc.nextInt();
			if(a==1) { //소비자모드
				userMode(sc, drink);
			}else if(a==2) {//관리자모드
				adminMode(ad, sc, drink);
			}
			else if(a==3) {//종료
				break;
			}
			else {//유효성검사
				System.out.println("잘못된 입력입니다.");
				System.out.println("다시입력하시겠습니까? Y/N");
				String YN=sc.next();
				YN=YN.toUpperCase();
				if(YN.equals("N")) {
					break;
				}
				continue;
			}
		}
		System.out.println("종료되었습니다.");
	}

 

2.userMode 메서드

	public static void userMode(Scanner sc,Drink[] drink) {
		int money;
		while(true) {
			System.out.println("돈을 얼마나 넣으시겠습니까?");
			money=sc.nextInt();
			if(money>=0) {
				break;
			}
			System.out.println("올바른 값을 입력해 주세요");
		}
		Pay pay=new Pay(money);

		System.out.println(pay.getMoney()+"원을 넣으셨습니다.");
		System.out.println();
		while(true) {  
			System.out.println("상품을 선택해주세요.");
			for(int i=1;i-1<drink.length;i++) {    
				System.out.println(i+"."+drink[i-1]);//음료메뉴 출력
			}

			int act=sc.nextInt()-1;//음료배열의 index
			int orders; //주문 수량을 입력하는 변수

			if(act<0||act>=drink.length) {//음료클래스의 음료갯수의 유효성검사
				System.out.println("잘못된입력입니다.");
				System.out.println();
				continue;
			}

			System.out.println(drink[act].getName()+"을 선택하셨습니다.");

			while(true) {
				System.out.println("수량을 입력하세요");
				orders=sc.nextInt();
				if(orders<=0) {//음료주문한 갯수가 음수면 잘못(유효성검사)

					System.out.println("잘못된입력입니다.");
					continue;

				}
				break;
			}
			pay.pay(drink[act], orders);//음료와 개수인자, 결제 진행
			
			System.out.println("주문을 계속하시겠습니까? Y/N");
			String YN=sc.next();
			YN=YN.toUpperCase();
			if(YN.equals("N")) {//입력한값이 N이면 반복문을 탈출
				break;

			}
		}
	}

 

3.관리자모드

	public static void adminMode(Admin ad,Scanner sc,Drink[] drink) {
		while(true) {
			System.out.println("관리자 비밀번호를 입력하세요.");
			if(ad.checkPW(sc.nextInt())) {//관리자객체에서 사용자가 입력한 패스워드와 같은지를 체크하는 함수수행
				while(true) {
					System.out.println();
					System.out.println("1.물품목록 2.물품수량추가 3.관리자모드 종료");
					int gmact=sc.nextInt();
					if(gmact==1) {
						for(int i=1;i-1<drink.length;i++) {
							System.out.println(i+"."+drink[i-1]);
						}
					}else if(gmact==2) {
						while(true) {
							for(int i=1;i-1<drink.length;i++) {
								System.out.println(i+"."+drink[i-1]);
							}

							System.out.println("추가할 물품은 선택해주세요.");
							int act=sc.nextInt()-1;
							int gmorders;//키보드로 추가물품갯수
							if(act<0||act>drink.length) {//음료배열유효성검사
								System.out.println("잘못된입력입니다.");
								System.out.println();
								continue;
							}

							System.out.println(drink[act].getName()+"을 선택하셨습니다.");
							while(true) {
								System.out.println("수량을 입력해주세요");
								gmorders=sc.nextInt();//키보드로 추가물품갯수를 입력
								if(gmorders<=0) {//추가물품의 유효성검사
									System.out.println("잘못된입력입니다.");
									continue;
								}
								break;
							}
							ad.plusCnt(drink[act], gmorders);
							System.out.println(drink[act].getName()+"의 수량을 "+gmorders+"개 추가하였습니다.");
							
							break;
						}

					}else if(gmact==3) {
						System.out.println("관리자모드를 종료하겠습니다.");
						break;
					}
					else 
						continue;
				}
				break;
			}else {//패스워드가 맞지 않다면
				System.out.println("잘못입력 하셨습니다.");
				System.out.println("다시입력하시겠습니까? Y/N"); 
				String YN=sc.next();
				YN=YN.toUpperCase();//소문자를 대문자로 바꾼다.
				if(YN.equals("N")) {
					break;
				}
			}
		}
	}

 

 

[내가 생각하는 보완점]

1. 상품목록을 보여주는 코드는 반복이 많이 되어 메서드로 빼면 코드의 재사용성이 증가할 것같다.

2. pk값을 제대로 활용하기 위해 커피의 값은 1001부터, 주스는 2001부터, 탄산은 3001, 이온은 4001부터 증가하는 코드로 구현하면 종류에따른 음료를 볼 수 있는 등 여러가지로 활용 가능할 것 같다.

  <구현방법: Drink클래스를 상속받는 클래스 각각에 pkNum을 초기화한다.>

3. 팀 프로젝트에서 처음으로 주도적인 역할을 하면서 의견을 조율하는 방법을 조금 더 생각해봐야겠다는 생각이 들었다.

 

[피드백]

1. 추상클래스는 추상메서드를 생성하기 위한 용도 뿐만아니라 객체를 생성시키지 않기 위해서라도 필요하다.

->abstract class Drink

2. Pay 클래스에 pay메서드를 넣었는데 혼동 가능성이 있기 때문에 구분할 필요가 있다.

3. 발표할시 인자가 어느 클래스에서 온건지, 어디 클래스로 가는 건지 명확하게 말할 필요가 있다.

댓글