Test/JAVA Test

MVC 음료 자판기 프로그램 + 장바구니

오류나면꽥꽥 2023. 5. 24. 20:27

 로그: 사용자가 새로 입장합니다.
=== 자 판 기 ===
1. 음료추가
2. 음료목록출력
3. 음료구매
4. 음료제거
5. 음료추가
6. 음료검색
7. 프로그램 종료
입력) 

 

 

 

View

 

package view;

import java.util.ArrayList;
import java.util.Scanner;

import model.DrinkVO;

public class DrinkView {

	private static Scanner sc=new Scanner(System.in);

	public int tryCatch() {
		while(true) {
			try {
				System.out.print("입력) ");
				int action=sc.nextInt();

				return action;
			}
			catch(Exception e) {
				sc.nextLine();
				System.out.println("정수로 입력해주세요!");
			}
		}
	}

	public int printMenu() {
		System.out.println("=== 자 판 기 ===");
		System.out.println("1. 음료추가");
		System.out.println("2. 음료목록출력");
		System.out.println("3. 음료구매");
		System.out.println("4. 음료제거");
		System.out.println("5. 음료추가");
		System.out.println("6. 음료검색"); // R : selectAll (2개이상)
		System.out.println("7. 프로그램 종료");
		while(true) {
			int action=tryCatch();
			if(1<=action && action<=7) {
				return action; // "유효성 검사" == 사용자의 입력값 검사
				// : 사용자의 입력값에 대하여 자료형(타입),범위 등을 확인하는 것
			}
		}
	}

	public String getDrinkName() {
		System.out.print("음료이름) ");
		String name=sc.next();
		return name;
	}
	public int getDrinkCnt() {
		System.out.print("음료재고입력) ");
		int cnt=sc.nextInt();
		return cnt;
	}
	public int getDrinkPrice() {
		System.out.print("음료가격입력) ");
		int price=sc.nextInt();
		return price;
	}

	// 음료 목록 출력
	public void printDrinkList(ArrayList<DrinkVO> datas) {
		if(datas.isEmpty()) {
			System.out.println("출력할 음료가 없습니다..");
			return;
		}
		for(DrinkVO v:datas) {
			System.out.println(v);
		}
	}

	public int getDrinkNum() {
		System.out.print("음료번호입력) ");
		int num=sc.nextInt();
		return num;
	}

	public void printTrue() {
		System.out.println("요청하신 서비스를 완료했습니다.");
	}

	public void printFalse() {
		System.out.println("요청하신 서비스는 현재 이용이 어렵습니다.");
		System.out.println("다음에 다시 이용해주시기 바랍니다.");
	}

	public void printEnd() {
		System.out.println("프로그램 종료...");
	}

}

 

OV

package model;

public class DrinkVO {
	private int num;
	private String name;
	private int price;
	private int cnt;
	public DrinkVO(int num,String name,int price,int cnt) {
		this.num=num;
		this.name=name;
		this.price=price;
		this.cnt=cnt;
	}
	public int getNum() {
		return num;
	}
	public void setNum(int num) {
		this.num = num;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getPrice() {
		return price;
	}
	public void setPrice(int price) {
		this.price = price;
	}
	public int getCnt() {
		return cnt;
	}
	public void setCnt(int cnt) {
		this.cnt = cnt;
	}
	@Override
	public String toString() {
		String msg=num+"번 "+name+" "+price+"원 ";
		if(this.cnt==0) {
			msg+="[X]";
		}
		else {
			msg+="["+cnt+"개]";
		}
		return msg;
	}
	@Override
	public boolean equals(Object obj) {
		DrinkVO drinkVO=(DrinkVO)obj;
		if(this.num==drinkVO.num) { // 내 PK와 비교대상의 PK가 같아?
			return true;
		}
		return false;
	}

}

 

DAO

package model;

import java.util.ArrayList;

// DAO의 CRUD(비즈니스 메서드, 핵심 로직)는
// 어떤 추가 요청사항에도 절대!
// "메서드 시그니처"가 변하지 않도록 코드를 작성해야함

// "메서드 시그니처"가 변경되면 다른 파트에 영향을 줘버림...
// '기능' 변경은 허용

// 결론) "메서드 시그니처"는 설계 단계에서 절대로 변경되면 안됨!
public class DrinkDAO {

	private static int PK=1001;
	private ArrayList<DrinkVO> datas;
	public DrinkDAO() {
		datas=new ArrayList<DrinkVO>();
		datas.add(new DrinkVO(PK++,"콜라",1200,3));
		datas.add(new DrinkVO(PK++,"사이다",900,2));
		datas.add(new DrinkVO(PK++,"환타",1500,1));
	}

	public boolean insert(DrinkVO vo) {
		datas.add(new DrinkVO(PK++,vo.getName(),vo.getPrice(),vo.getCnt()));
		return true;
	}

	// 1. 전체 목록 출력 => 그냥 내가 가진 멤버변수 datas 반환
	// 2. 검색 결과 출력 => 이름을 보고, 그 이름을 가진 애들을 반환

	public ArrayList<DrinkVO> selectAll(DrinkVO vo) {
		if(vo.getName()== null) { // 전체목록출력
			return datas;
		}
		else { // 검색을 했다면
			ArrayList<DrinkVO> datas=new ArrayList<DrinkVO>();
			for(DrinkVO data:this.datas) {
				if(data.getName().contains(vo.getName())) { // 검색 이름이 data 이름에 존재해?
					datas.add(data);
					//	이름을 보고 
					//	새로운 datas를 만들어서
					//	이름을 가진 애들을 넣어서 반환
				}
			}
			return datas;
		}
	}


	public DrinkVO selectOne(DrinkVO vo) { // PK
		for(DrinkVO data:datas) {
			if(data.getNum()==vo.getNum()) {
				DrinkVO dVO=new DrinkVO(data.getNum(),data.getName(),data.getPrice(),data.getCnt());
				return dVO;
				// 실제 DB 데이터(==datas)를 전송 xxx
				// 새로 vo객체를 new(객체화)해서 전송 ooo
			}
		}
		System.out.println(" 로그: selectOne(): 해당상품없음");
		return null;
	}

	// 오버로딩이 불가능한 기능일 경우,
	// 기능이 매우 유사한 것이기 때문에 내부 로직에서 분리하여 관리
	// -> 유사한 기능끼리 묶어서 관리하는 것이 용이하기 때문
	//    == 응집도를 높임 -> 유지보수에 용이
	public boolean update(DrinkVO vo) {
		for(DrinkVO data:datas) {
			if(data.getNum()==vo.getNum()) { // 상품을 찾았을 때
				// 구매할 때에는 절대값이랑 내 재고랑 비교
				if(vo.getCnt()<0) { // 구매할 때 
					int cnt=vo.getCnt()*(-1); // 구매하려는 양
					if(cnt>data.getCnt()) {
						System.out.println(" 로그: update(): 재고없음");
						return false;					
					}
				}
				data.setCnt(data.getCnt()+vo.getCnt());
				return true;
			}
		}
		System.out.println(" 로그: update(): 해당상품없음"); // 상품을 못찾았을때
		return false;
	}

	public boolean delete(DrinkVO vo) {
		for(int i=0;i<datas.size();i++) {
			if(datas.get(i).getNum()==vo.getNum()) {
				datas.remove(i);
				return true;
			}
		}
		System.out.println(" 로그: delete(): 해당상품없음");
		return false;
	}
}

 

Controller

package controller;

import java.util.ArrayList;

import model.DrinkDAO;
import model.DrinkVO;
import view.DrinkView;

public class DrinkCtrl {
	private DrinkView view;
	private DrinkDAO dao;
	public DrinkCtrl() {
		view=new DrinkView();
		dao=new DrinkDAO();
	}

	public void startApp() {
		while(true) {

			System.out.println(" 로그: 사용자가 새로 입장합니다.");
			// 로그
			// 확인을 위한 것
			// 실제 서비스에서 출력 x
			ArrayList<DrinkVO> cart=new ArrayList<DrinkVO>(); // 장바구니 장바구니=초기화;


			// 음료 여러개 구매할 때
			while(true) {
				int action=view.printMenu();

				if(action==1) {
					String name=view.getDrinkName();
					int price=view.getDrinkPrice();
					int cnt=view.getDrinkCnt();
					DrinkVO vo=new DrinkVO(0,name,price,cnt); // 주지 않아도 되는 값은 0, null

					// DAO의 CRUD에게 전달해야하는 값만 설정
					// 전달하지 않아도 되는 값들은 0, null 등으로 설정
					// DrinkVO vo 잠깐 만들어서 값을 주고 없어지는 친구

					if(dao.insert(vo)) {
						view.printTrue();
					}
					else {
						view.printFalse();
					}
				}
				else if(action==2) {
					ArrayList<DrinkVO> datas=dao.selectAll(new DrinkVO(0,null,0,0));
					view.printDrinkList(datas);
				}
				else if(action==3) {
					int num=view.getDrinkNum();
					int cnt=1;
					DrinkVO vo=new DrinkVO(num,null,0,-cnt);
					if(dao.update(vo)) {
						// 구매에 성공했을 때에만 장바구니에 해당 상품을 추가
						// 장바구니.add(내가 구매한 상품);
						DrinkVO data=dao.selectOne(vo); //  pk 이름 가격 몇개 샀는지 알아야함
						data.setCnt(cnt); // pk name price는 자판기에 저장된 정보로 가능하지만,
						// cnt는 사용자가 입력했던 정보로 변경해야함


						boolean flag=false;
						int index=0;
						for(int i=0;i<cart.size();i++) {
							if(data.equals(cart.get(i))) {
								index=i;
								flag=true;
							}
						}
						if (flag){ 
							//재고 변경이야~
							cart.get(index).setCnt(cart.get(index).getCnt()+cnt);
						}
						else {
							cart.add(data); // 장바구니.add(내가 구매한 상품);
						}
						view.printDrinkList(cart);
						view.printTrue();
					}
					else {
						view.printFalse();
					}
				}
				else if(action==4) {
					int num=view.getDrinkNum();
					DrinkVO vo=new DrinkVO(num,null,0,0);
					if(dao.delete(vo)) {
						view.printTrue();
					}
					else {
						view.printFalse();
					}
				}
				else if(action==5) {
					int num=view.getDrinkNum();
					int cnt=view.getDrinkCnt();
					DrinkVO vo=new DrinkVO(num,null,0,cnt);
					if(dao.update(vo)) {
						view.printTrue();
					}
					else {
						view.printFalse();
					}
				}
				else if(action==6) {
					String name=view.getDrinkName();
					ArrayList<DrinkVO> datas=dao.selectAll(new DrinkVO(0,name,0,0));
					view.printDrinkList(datas);
				}

				else if(action==7) {
					view.printEnd();
					break;
				}
			}
			System.out.println(" 로그: 사용자가 나갑니다. ");
			cart.clear(); // 필수는 아니지만 한번더 확인차
		}
	}

}

 

Client

package client;

import controller.DrinkCtrl;

public class Client {
	public static void main(String[] args) {
		
		DrinkCtrl app=new DrinkCtrl();
		app.startApp();

	}
}