열심히 끝까지
디바이스 융합 자바(Java) day18 - [재코딩] 자판기 with MVC 본문
디바이스 융합 자바(Java) day18 - [재코딩] 자판기 with MVC
노유림 2022. 6. 30. 15:43[day18]
클라이언트
ex)
사용자
웹 브라우저
>> 같은 단어
>> 어플 객체
Controller app = new Controller();
app -> new 어플 객체
- 유지보수가 용이한 프로그램 제작하려면?
> 모듈의 크기를 줄여야 한다.(잘게잘게 쪼개야 한다)
ex ) 레고
: 크기가 큰 레고조각으로 만들 수 있는 것이 얼마 없지만
크기가 작은 여러 개의 레고조각으로는
여러가지를 만들 수 있다.
사용자가 View에서 입력한 값들은 Controller까지 도착한다!
Why?
>> Controller에서 View의 메서드를 호출했기 때문!
>> 추가를 하면...
> 사용자가 추가하려고 잠깐잠깐 입력한 것들은 갈색
천년만년 저장하는 것이 아니기 때문에 지역변수!
> Controller에서는 사용자가 입력한 값을
일반변수(지역변수!, 멤버변수가 아니다!!)에 저장해둔다.
>> Model에서는 실질적인 기능을 수행한다!!
>> 핵심 로직/ 비즈니스 메서드/ CRUD
: 사용자가 입력한 값을 필요로 하므로
Controller가 이 값을 전달해준다!
---ProductVO-------
package model;
// 웹 개발에서, 일반적으로 기본생성자를 사용하여 VO를 생성(new)
public class ProductVO {
private int num; // PK
private String name;
private int cnt; // 재고 데이터
private int price;
/*
public ProductVO(int num, String name, int price) {
this(num, name, price, 0);
// 재고 지정이 안되어 있으면 0으로 디폴트
}
public ProductVO(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 getCnt() {
return cnt;
}
public void setCnt(int cnt) {
this.cnt = cnt;
}
public int getPrice() {
return price;
}
public void setPrice(int price) {
this.price = price;
}
@Override
public String toString() {
return "ProductVO [num=" + num + ", name=" + name + ", cnt=" + cnt + ", price=" + price + "]";
}
}
---ProductDAO-------
package model;
import java.util.ArrayList;
// CRUD
// 주석으로 좀 크게 쳐져있는 코드는 내가 짠 코드
// 강사님으 코드와 비교해서 해볼 것!
public class ProductDAO {
// DB를 대체하는 컬렉션(배열리스트)
ArrayList<ProductVO> datas;
private int pk = 101; // 후위증감 연산을 선호한다
// 어딘가에서 DAO 사용할텐데,
// DAO가 생성되면 그 즉시 datas도 생성되게끔 하고 싶다!
// == DAO의 멤버변수인 datas도 값을 가질 수 있게 만들고 싶어요~
// 생성자를 써야한다.
public ProductDAO() { // default로 만들면 다른 패키지에서 쓸 수 없다...
// 앞으로 public을 붙여서 사용!
datas= new ArrayList<ProductVO>();
ProductVO vo = new ProductVO();
/*
ProductVO vo1 = new ProductVO();
ProductVO vo2 = new ProductVO();
ProductVO vo3 = new ProductVO();
*/
// 초기데이터(혹은 샘플 데이터)
/*
datas.add(new ProductVO(pk++, "콜라", 1200));
datas.add(new ProductVO(pk++, "사이다", 900, 5));
datas.add(new ProductVO(pk++, "환타", 800, 2));
*/
/*
vo1.setName("콜라");
vo1.setPrice(1200);
vo1.setNum(pk++);
datas.add(vo1);
vo2.setName("사이다");
vo2.setPrice(900);
vo2.setCnt(5);
vo2.setNum(pk++);
datas.add(vo2);
vo3.setName("환타");
vo3.setPrice(800);
vo3.setCnt(2);
vo3.setNum(pk++);
datas.add(vo3);
*/
vo.setCnt(2);
vo.setName("콜라");
vo.setNum(pk);
vo.setPrice(1000);
}
// 관리자
// 새로운 음료 추가
// 음료 재고 추가
// 음료 삭제
// 사용자(서비스)
// 음료 출력
// 음료 구매
public ArrayList<ProductVO> selectAll(ProductVO vo) { // getAll()
//DB에서는 선택하는 행위를 SelectAll()로 쓰이는 경우가 많다.
// 여기서 출력을 한다?? 잘못된거다!
// 직접 로직을 구현하는 경우가 있는데 그거 잘못된것이다!!
// View측에서 무엇을 필요로 할 지 고려!
System.out.println("로그 : selectAll()");
return datas;
}
public ProductVO selectOne(ProductVO vo) { // getOne() R에 해당
for(ProductVO data : datas) {
if(data.getNum() == vo.getNum()) {
System.out.println("로그 : " + data + " 반환");
return data;
}
}
System.out.println("로그 : 반환xxx -> 확인 필요!");
return null; // 만날 확률이 거의 없다.
// 이상한 숫자가 들어오게 되면 null값을 되돌려준다.
// 이상한 숫자가 들어올 일이 없기 때문이다.
// 유효성검사를 View가 해줄 것이다.
}
// 음료 구매
// 사용자가 pk 입력
// pk에 해당하는 음료를 출력
// 구매 시도 시 음료의 재고 --
/*
public boolean buy(ProductVO vo) { // U에 해당
// 실무에서는 다르게 작성하기도 하다(void도 하지만 boolean값도 쓰인다
// update의 성공 여부
if(vo==null) {
System.out.println("없는 메뉴입니다!");
return false;
}
if(vo.getCnt()==0) {
System.out.println("로그 : " + vo.getNum() + " 재고가 없습니다.");
return false;
}
vo.setCnt(vo.getCnt()-1);
System.out.println("로그 : " + vo.getNum() + " 구매 완료!");
return true;
}
*/
// 음료추가
/*
public boolean insert(ProductVO vo) {
// boolean값으로 하는 것이 일반적이다 => 성공하면 true, 실패하면 false
// 현재 프로그램 생성자가 오버로딩되어있어서
// 재고가 없어도 메뉴생성이 가능함
// -> 메서드 오버로딩
return false;
}
*/
public boolean insert(ProductVO vo) {
// 강사님의 코드
try {
vo.setNum(pk++);
datas.add(vo);
}catch(Exception e) {
e.printStackTrace();
return false;
}
return true;
/* 고쳐본 코드
try {
// productVO에 새 값 추가
vo.setNum(pk++);
datas.add(vo);
System.out.println(" 로그 : 메뉴추가성공!");
return true;
}
catch(Exception e){ // 예외발생 시 로그 남겨주기
System.out.println(" 로그 : 메뉴추가실패 : 확인이 필요한 예외발생!");
e.printStackTrace(); // 어떤 예외인지 출력!
return false;
}
*/
}
// 재고 추가
// 1. 결제를 하면 -1만 되는(한 개씩만 구매가 되는 상황)
// 2. 결제가 원하는 개수만큼 되는 것 -N
// 3. 결제 완료 시 총 금액 => 재고 혹은 금액을 반환하려면 뭐가 반환될지 몰라 ProductVO를 출력값을 해야 함
// Controller에서 update를 마치고 selectOne()을 수행하는 것이 낫다
// 4. 재고를 추가했을 때 추가 되는 것 +N
public boolean update(ProductVO vo) { // 상품 넘버, 재고량!
for(ProductVO data : datas) { // 처음부터 끝까지 돈다
if(data.getNum()==vo.getNum()) { // 만약 넘버가 같으면?
data.setCnt((data.getCnt()+vo.getCnt()));
// M: 결제를 할지, 재고추가를 할 지 난 모름
// -값 +값
return true; // 성공하면 true반환
}
}
return false; // 실패
}
public boolean delete(ProductVO vo) {
for(ProductVO data : datas) {
if(data.getNum()-100==vo.getNum()) {
datas.remove(data);
return true;
}
}
return false; // 실패
}
}
// 이걸로 model의 역할을 끝!
---ProductView-------
package view;
import java.util.ArrayList;
import java.util.Scanner;
import model.ProductVO;
public class ProductView {
Scanner sc = new Scanner(System.in);
public int action;
public void startView() {
while(true) { // 유효성 검사 -> 꼼꼼하게 작업해보기!
System.out.println("=== 자판기 ===");
System.out.println("1.메뉴확인 2.구매 3.종료");
System.out.print("입력) ");
action = sc.nextInt();
if(action >= 1 && action <=3 || action == 1234) { // 관리자모드 1234
break;
}
System.out.println("범위외입력!");
}
}
/*
public void manageView() {
while(true) {
System.out.println("=== 관리자모드 ===");
System.out.println("1.음료추가 2.음료재고추가 3.음료삭제 4.종료");
System.out.print("입력) ");
action = sc.nextInt();
if(action >= 1 && action <= 4) {
break;
}
System.out.println("범위외입력!");
}
}
public void funcM1(ArrayList<ProductVO> datas) {
System.out.print("추가할 음료와 가격을 입력하세요) ");
String name = sc.next();
int price = sc.nextInt();
}
*/
public void func1(ArrayList<ProductVO> datas) {
int i = 1;
for(ProductVO vo : datas) {
System.out.println(i + "번 메뉴 " + vo.getName() + "[" + vo.getCnt() + "] : " + vo.getPrice() );
i++;
}
}
public int func2(ArrayList<ProductVO> datas) {
for(int i = 0; i < datas.size(); i++) { // 다시 한번 출력 + 재고도 체크
System.out.print(datas.get(i).getNum()+"번 메뉴");
if(datas.get(i).getCnt()==0) {
System.out.println("x");
continue;
}
System.out.println(datas.get(i).getName());
}
while(true) {
System.out.print("메뉴 입력 ) ");
int menu = sc.nextInt();
if(1<=menu && menu <= datas.size()) {
return menu;
}
System.out.println("상품번호 확인 후 다시 입력해주세요!");
}
// action += 100; -> Controller 에서 해야한다고 강사님은 생각!
// 상품번호가 몇번인지 모르는게 맞기 때문에!
}
public void funcT(ProductVO vo) {
System.out.println(vo.getName() + "구매완료!");
}
public void funcF(ProductVO vo) {
System.out.println(vo.getName() + " 재고가 없습니다...");
}
public void func3() {
System.out.println("프로그램이 종료됩니다");
for(int i = 0; i < 5; i++) {
System.out.println(".");
try {
Thread.sleep(1000); // 1000당 1초 재운다 == sleep
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println();
}
// 1~3 메뉴를 보여주는 출력문구(겹친건 지운다)
// 음료추가
// 음료이름입력
// 음료가격입력
// 음료재고입력
// 음료 삭제
// 수행이 완료되었습니다!(삭제 + 추가)
// 수행실패! 다음에 다시 이용해주세요..
// 음료재고추가
// 번호입력
// 음료삭제
// 번호입력<- 위에 있으니 필요없다
public void admin_func1() { // 관리자모드
// return할 필요없이 이렇게 진행해도 된다!
while(true) { // 무한반복(if문 확인되면 break)
System.out.println("=== 관리자 모드 ===");
System.out.println("1.음료추가 2.재고추가 3.음료삭제 4.관리자모드 종료");
System.out.print("입력) ");
action = sc.nextInt();
if(1<=action&&action<=4) {
break;
}
System.out.println("범위외입력!");
}
}
public void admin_func2() { // 음료 추가
System.out.println("음료추가 메뉴입니다.");
}
// 음료를 만드는 메서드로 묶어버리면
// 재고를 추가하는 기능을 한번 더 만들어야한다.
// 한 줄만 뜰 수 있게 만들게 다 따로 만드는 것이 좋다!!
public void admin_func3() { // 음료이름입력
System.out.println("음료 이름을 입력해주세요... ");
}
public void admin_func4() { // 음료가격입력
System.out.println("음료 가격을 입력해주세요... ");
}
public void admin_func5() { // 음료재고입력
System.out.println("음료 재고를 입력해주세요... ");
}
public void admin_func6() { // 수행이 완료되었습니다!
System.out.println("수행이 완료되었습니다!");
}
public void admin_func7() { // 수행실패! 다음에 다시 이용해주세요...
System.out.println("수행실패! 다음에 다시 이용해주세요...");
}
public void admin_func8() { // 음료재고추가
System.out.println("음료재고추가 메뉴입니다.");
}
public void admin_func9() { // 번호입력
System.out.print("번호를 입력해주세요... ");
}
public void admin_func10() { // 음료 삭제
System.out.println("음료삭제 메뉴입니다.");
}
public int inputInt() {
System.out.print("정수 입력) ");
int i = sc.nextInt();
return i;
}
public String inputString() {
System.out.print("문자열 입력) ");
String str = sc.next();
return str;
}
}
---ProductController-------
package controller;
import model.ProductDAO;
import model.ProductVO;
import view.ProductView;
public class ProductController {
ProductDAO model;
ProductView view;
public ProductController() {
model = new ProductDAO();
view = new ProductView();
}
public void startApp() {
while(true) {
view.startView();
if(view.action==1) {
ProductVO vo = new ProductVO();
view.func1(model.selectAll(vo));
}
else if(view.action==2) {
ProductVO vo = new ProductVO();
int num = view.func2(model.selectAll(vo));
// 사용자가 먹고 싶은 메뉴의 번호를 입력햇는데,
// C에서 [view.action]
// C 에서는 사용자가 입력한 메뉴의 번호를 view.action으로 참조 가능하고,
// M은 pk를 입력받으면 상품객체를 줄 준비가 되어있습니다.
vo.setNum(num);
vo = model.selectOne(vo);
// pk를 넣으면 해당하는 상품을 반환하는 M의 selectOne()메서드
if(vo==null) {
continue;
}
vo.setCnt(/*vo.getCnt()*/-2);
System.out.println("로그1 : "+vo);
boolean flag = model.update(vo);
// M은 반환받은(==사용자가 선택한) 객체의 재고를 --
System.out.println("로그2 : " + model.selectOne(vo));
ProductVO data2 = model.selectOne(vo);
int cnt = vo.getCnt();
// 구매한 개수
int price = data2.getPrice();
int total = cnt*price*-1;
System.out.println("로그 : 총 결제 금액은 : " + total + "원");
// boolean flag=model.update(model.selectOne(view.action+100)); // 상품객체 전달
if(flag) {
view.funcT(vo);
}
else {
view.funcF(vo);
}
}
else if(view.action==3) {
view.func3();
break;
}
else if(view.action == 1234) { // 관리자모드
while(true) {
view.admin_func1();
if(view.action==1) { // 메뉴 추가
ProductVO vo = new ProductVO();
view.admin_func2();
view.admin_func3();
String name = view.inputString();
vo.setName(name);
view.admin_func4();
int price = view.inputInt();
vo.setPrice(price);
view.admin_func5();
int cnt = view.inputInt();
vo.setCnt(cnt);
boolean flag = model.insert(vo);
if(flag) { //
view.admin_func6();
}
else {
view.admin_func7();
}
}
else if(view.action==2) { // 메뉴 재고 업데이트
ProductVO vo = new ProductVO();
view.admin_func8();
view.func1(model.selectAll(vo)); // 메뉴 전부 호출
view.admin_func9(); // 메뉴번호
int num = view.inputInt();
view.admin_func5(); // 메뉴 재고
int cnt = view.inputInt();
vo.setNum(num);
vo.setCnt(cnt);
boolean flag = model.update(vo);
if(flag) { // 만약 업데이트가 되면?
view.admin_func6(); // 출력
}
else {
view.admin_func7();
}
}
else if(view.action==3) { // 메뉴 제거
ProductVO vo = new ProductVO();
view.admin_func10();
view.admin_func9();
int num = view.inputInt();
vo.setNum(num);
boolean flag = model.delete(vo);
if(flag) {
view.admin_func6();
}
else {
view.admin_func7();
}
}
else if(view.action==4) {
view.func3(); // 숫자넣지 말고 영어로 기능을 유추할 수 있게
break;
}
}
}
}
}
}
'디바이스 융합 자바(Java)기반 풀스택 개발자 양성과정(수업내용)' 카테고리의 다른 글
디바이스 융합 자바(Java) day20 - 오라클(GROUP BY절,HAVING절,실행순서,페이징처리,조인(JOIN)-이퀄조인),자바&데이터베이스 연결 및 실습(추가,삭제,선택,목록출력) (0) | 2022.07.04 |
---|---|
디바이스 융합 자바(Java) day19 - 오라클(SQL)설치 및 실행,생성,삽입 (0) | 2022.07.01 |
디바이스 융합 자바(Java) day17 - 학생부 프로그램 with MVC (0) | 2022.06.29 |
디바이스 융합 자바(Java) day16 - MVC기본,자판기 프로그램 with MVC (0) | 2022.06.28 |
디바이스 융합 자바(Java) day15-1 - MVC 기초개념 (0) | 2022.06.27 |