열심히 끝까지
[코딩 예시] - 6/28 MVC 자판기 프로그램 + 관리자 추가 과제 본문
[자판기 프로그램] MVC
[설계]-------------
주제 : 자판기 프로그램 with MVC
요구사항
- 관리자 모드
- 재고 데이터
- MVC 역할분담을 제대로
- 각 파트에 2.2.2
- 문서화(버전 관리) + 회의 내용 기록
Model 파트---------
- VO : 데이터 정의
- 자판기 안의 제품
: PK(중요!!)
: 제품 이름
: 제품 가격
: 재고 데이터
- DAO : 비즈니스 메서드(핵심로직, CRUD)
무슨 행동을 할지 정의
VO를 가지고 어떤 동작을 할 지 고민
- 데이터 추가(C) : Insert
: 새로운 음료 혹은 재고를 추가하는 행위
>> "관리자"의 작업
- 데이터를 출력(보여주는 행위 V)
: 음료를 보여주는 행위
>> 서비스
: 음료를 구매하는 행위
>> 서비스(행위)
- 데이터를 삭제하는 행위(D)
: 기존의 음료 메뉴를 삭제하는 행우
>> 관리자
- 데이터를 검색하는 행위
: 음료를 검색해서 찾는 행위
>> 서비스
> 근데 이번에 안다룸.. 검색하는 서비스는!
View 파트------------
- UI/UX
User Flow
사용자의 편의성을 도모
사용자가 입력한 값을 유효성 검사
사용자만을 위한 파트이기에 메뉴 추가는 안들어간다!!
1) 전체메뉴
===자판기===
1. 메뉴확인 2. 구매 3. 종료
2) 1번을 눌렀을 때 사용자에게 제공될 화면
: 현재 DB(음료들을 N개 저장할 객체)에 존재하는 메뉴들을 출력
ㄴ> 컬렉션 : ArrayList(배열리스트)
3) 2번을 눌렀을 때 사용자에게 제공될 화면(1)
: ㅁㅁ 구매 완료되었습니다!!
4) 2번을 눌렀을 때 사용자에게 제공될 화면(2)
: ㅁㅁ 재고가 없습니다...
>> 버튼을 눌렀을 때, 재고가 없는 친구라고 띄어도 됨
5) 3번을 눌렀을 때 사용자에게 제공될 화면
: 프로그램이 종료됩니다...
Controller 파트-----------
- Model - View 연결다리 역할
: View_1()이 실행
if 1번을 눌렀다면? View_2();
2번을 눌렀다면? View_3() or View_4()
>> Model을 참고하여 누가 나올지를 결정!!
3번을 눌렀다면? View_5();
4, 0, -1 이런 거 눌렀다면?(1,2,3이 아닌 다른 값이 들어오면?)
>> View 작업자에게 요청
: 근데 controller가 짜고 있다면..?
> 그건 나쁜 행위..!!!
> 외부로 옮겨지게 되면 데이터를 많이 잡아먹는다.
------------------실제 사례
1) M에서 기존의 음료메뉴 삭제() 구현
>> 내부 구현 로직이 이상한 로직으로 구현된 상태!!
2) M에서 기존의 음료메뉴 삭제() 잘 구현
>> Controller에서 Model을 불러오는 과정에서 잘못 호출을 함!
동일한 문제인데 누가 어떤 잘못을 했는지에 따라
누가 고치는지 달라짐!!!
맡은 바를 잘 살펴볼 것!!!
>> 잘 판단할 줄 알아야 한다!!
--------강사님의 자판기 프로젝트 코딩------
------modelVO----------
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 + "]";
}
}
-----ModelDAO---------
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>();
// 초기데이터(혹은 샘플 데이터)
datas.add(new ProductVO(pk++, "콜라", 1200));
datas.add(new ProductVO(pk++, "사이다", 900, 5));
datas.add(new ProductVO(pk++, "환타", 800, 2));
}
// 관리자
// 새로운 음료 추가
// 음료 재고 추가
// 음료 삭제
// 사용자(서비스)
// 음료 출력
// 음료 구매
public ArrayList<ProductVO> selectAll() { // getAll()
//DB에서는 선택하는 행위를 SelectAll()로 쓰이는 경우가 많다.
// 여기서 출력을 한다?? 잘못된거다!
// 직접 로직을 구현하는 경우가 있는데 그거 잘못된것이다!!
// View측에서 무엇을 필요로 할 지 고려!
System.out.println("로그 : selectAll()");
return datas;
}
public ProductVO selectOne(int num) { // getOne() R에 해당
for(int i = 0; i < datas.size(); i++) {
if(num==datas.get(i).getNum()) {
System.out.println("로그 : " + datas.get(i) + " 반환");
return datas.get(i);
}
}
System.out.println("로그 : 반환xxx -> 확인 필요!");
return null; // 만날 확률이 거의 없다.
// 이상한 숫자가 들어오게 되면 null값을 되돌려준다.
// 이상한 숫자가 들어올 일이 없기 때문이다.
// 유효성검사를 View가 해줄 것이다.
}
// 음료 구매
// 사용자가 pk 입력
// pk에 해당하는 음료를 출력
// 구매 시도 시 음료의 재고 --
public boolean update(ProductVO vo) { // U에 해당
// 실무에서는 다르게 작성하기도 하다(void도 하지만 boolean값도 쓰인다
// update의 성공 여부
if(vo.getCnt()==0) {
System.out.println("로그 : " + vo.getNum() + " 재고가 없습니다.");
return false;
}
vo.setCnt(vo.getCnt()-1);
System.out.println("로그 : " + vo.getNum() + " 구매 완료!");
return true;
}
}
// 이걸로 model의 역할을 끝!
-----View-----------
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 func1(ArrayList<ProductVO> datas) {
for(int i = 0; i < datas.size(); i++) {
System.out.println((i+1)+"번 메뉴 " + datas.get(i).getName());
}
}
public void func2(ArrayList<ProductVO> datas) {
for(int i = 0; i < datas.size(); i++) {
System.out.print((i+1)+"번 메뉴 " + datas.get(i).getName());
if(datas.get(i).getCnt()==0) {
System.out.println("x");
continue;
}
System.out.println(datas.get(i).getCnt());
}
while(true) {
System.out.print("메뉴 입력 ) ");
action = sc.nextInt();
if(1<=action && action <= datas.size()) {
break;
}
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();
}
}
}
}
---------Controller-----------
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) {
view.func1(model.selectAll());
}
else if(view.action==2) {
view.func2(model.selectAll());
// 사용자가 먹고 싶은 메뉴의 번호를 입력햇는데,
// C에서 [view.action]
// C 에서는 사용자가 입력한 메뉴의 번호를 view.action으로 참조 가능하고,
// M은 pk를 입력받으면 상품객체를 줄 준비가 되어있습니다.
int num =view.action;// V에서 사용자가 입력한 메뉴 번호 pk 해당
ProductVO vo = model.selectOne(num+ 100);
// pk를 넣으면 해당하는 상품을 반환하는 M의 selectOne()메서드
boolean flag = model.update(vo);
// M은 반환받은(==사용자가 선택한) 객체의 재고를 --
// 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;
}
}
}
}
-------Client-----------
package client;
import controller.ProductController;
public class Client {
public static void main(String[] args) {
// 지금까지 만든 APP을 수행시킬 공간
// main()이 존재함
ProductController app = new ProductController();
app.startApp();
}
}
+ 과제
[V]
1. === 관리자 모드 ===
1) 음료 추가
2) 음료 재고 추가
3) 음료 삭제
2. 추가할 음료의 정보를 입력하세요
3. 추가할 음료의 번호와 개수를 입력하세요
4. 삭제할 음료의 번호를 입력하세요.
[M]
[C]
-----------------> 관리자 추가해보기
'디바이스 융합 자바(Java)기반 풀스택 개발자 양성과정(과제)' 카테고리의 다른 글
[코딩 과제] - 7/4 강사님 문제 (0) | 2022.07.04 |
---|---|
[코딩 과제] - 6/29 MVC 자판기 프로그램 + 관리자 프로그램 (0) | 2022.06.29 |
[코딩 문제] - 6/27 강사님 문제 (0) | 2022.06.27 |
[능력단위평가] - 6/27 문제 답안 (0) | 2022.06.27 |
[코딩 문제] - 6/24 강사님 문제 (0) | 2022.06.24 |