JAVA를 잡아라!...

JAVA_MVC_#3_자판기.ver1 (DAO,DTO 1개) 본문

JAVA/JAVA_복습문제

JAVA_MVC_#3_자판기.ver1 (DAO,DTO 1개)

onivv 2023. 12. 14. 23:27

헷갈리는 코드

- 메소드의 output이 void일 때... return이 있어야 하는 경우

- 메소드의 output이 반환을 해야할 때... if문 사용 시 이도저도아닌 상황에서 반환이 필수인 경우

                                                                (if문 안에만 return하면 안됨)

....

 

문제 한글코딩

 

Client

설치 : 컨트롤러의 객체 불러오기
실행 : 객체안에 메소드() 실행

 

ProductDTO

상품이라면 data를 가져야함
- 멤버변수	: (모두 private) PK, 이름, 가격, 재고
		+ String setSearchCondition (JAVA로직에서만 사용하는 변수, 검색조건 확인용)
		+ int addCnt (추가할 재고)
- getter & setter : private 멤버변수이니까 생성해주기
- @toString
------------------------------------------------------
웹 개발에서는 ★기본 생성자★를 원칙으로 함
    컨트롤러에서 생성자를 new할때 생성자의 인자로 넣는 값 중에서,
    어떤값이 정말 유효한 값인지 파악하기 어려움!
    ==> DTO에서 생성자를 따로 만들지 않음

 

ProductDAO

- 멤버변수	: 상품들이 저장될 수 있는 DB공간이 필요. ArrayList
- 생성자	: 멤버변수 초기화
			sample) 샘플데이터 추가는 기본생성자로 만들기 때문에 setter를 넣어주기

- CRRUD
	C, U, D : output이 boolean으로 고정되어있다면 성공/실패 반환
				결합도를 낮추기 위해 인자를 DTO로 둠!
	하나 이상 반환할 경우 --> ArrayList 반환
	하나만 반환할 경우 --> DTO 객체 하나 반환

< R - selectOne >
	인자로 받아온 객체의 PK를 객체배열의 처음부터 끝까지 돌면서 PK일치하는 객체배열의 객체 찾기
	if(인자객체PK == 객체배열 객체PK)
		찾으면 true, break
	없다면 return null
	있다면 return PK일치하는 객체
    
< R - selectAll >
	[전체출력]
		if(DTO의 searchCondition이 null이라면)
		기존배열 반환
	[이름검색]
		else if(DTO의 searchCondition이 "이름검색"이라면)
		새로운 객체배열에 사용자가 원하는 이름의 객체를 저장
		새로운배열 반환
	return null //전체출력도 아니고, 이름검색도 아니면 빈값 반환
    
< C - insert >
	new 객체를 생성 (기본생성자를 사용하기 때문에 setter를 모두 사용)
	이 객체의 번호, 이름, 가격, 재고에
	인자로 받아온 객체의 get(번호, 이름, 가격, 재고)를 set(저장)
	배열에 객체를 추가!
	+) 메모리공간 부족, 정전,... 혹시 모르니까 예외처리 필요. try-catch
    
< U - update >
	selectOne에서 합격한 인자를 받아오기 때문에 객체PK번호를 확인하는 로직은 없앰
		컨트롤러에서 update()나 delete()같은 기능을 수행할때에는
		selectOne()을 먼저 수행한 다음에 진행!
		따라서 이 상품은 100% 있다고 확신함!
        
	if (이 객체의 getSetSearchConditoin이 "구매"라면)
		이 객체의 재고 = 이 객체의 기존재고 -1 한 값을 저장
	else if (이 객체의 getSetSearchCondition이 "재고변경"이라면)
		이 객체의 재고 = 인자로 받아온 객체의 재고를 저장
	else if (이 객체의 getSetSearchCondition이 "재고추가"이라면)
		이 객체의 재고 = 인자로 받아온 객체의 재고를 저장  
	else if (이 객체의 getSetSearchCondition이 "가격변경"이라면)
		이 객체의 가격 = 인자로 받아온 객체의 가격를 저장
	else {return false}	//구매, 재고변경, 재고추가, 가격변경 아무것도 해당안되면 false반환
	return true		//해당되면 true반환

 

View

사용자에게 보여주고 입력을 받아야하니까
Scanner사용!
메소드 시그니쳐 잘 생각하기... input, output 생각하기

 

Controller

- 멤버변수	: private (DAO, View) //DTO는 그냥 자료형(type)일 뿐 import만 해주자
- 생성자	: 초기화해주자

모델과 뷰를 조합해서 코딩하기

< 사용자 모드 >
1. 전체목록
	DAO야 전체 목록좀 줄래
	아무것도 보낼 데이터 없어서 null로 했지만
	객체를 new해서 객체를 넣어줌
	view에서 받아와서 출력!
2. 상품검색
	view로 사용자에게 상품번호PK 받기
	DAO에 인자로 보내줄 객체 생성
	그 객체에 PK번호 저장
	이 객체의 PK번호를 검사해 객체 배열에 있으면
	있던 객체를 data에 저장
	사용자가 입력한 PK번호와 일치하는 객체 하나를 출력
	if(구매성공이라면)
		DAO야 update해
	있으면 true
	없으면 false
3. 이름으로 상품검색
	view로 사용자에게 이름 받아오기
	new 객체에 이름 set
	new 객체에 searchCondition "이름검색" set
	productDAO의 selectAll의 인자로 객체 input
	객체배열에 저장
	view에서 이 객체배열을 input으로 받아 출력
    
< 관리자 모드 >
1. 상품추가
	어떤 이름, 가격, 재고를 --> setter 저장!
	새로운 객체를 만들어서 이 객체에 이름, 가격, 재고 저장
	만든 객체를 insert
2. 재고변경
	view한테 PK입력받기 --> PK를 DTO한테 넘겨주면
	있다면(DTO) 진행,
	없다면(null) 위로..넘어가지 못함
	있을때, 재고 몇으로 바꿀까? view에서 사용자에게 재고 받기
	재고 바꿀거야...있는지없는지 확인하고 없으면 continue해서 다시 올라가
	100% 있다고 생각
	DTO에서 update()
3. 상품재고추가
	재고변경과 유사한 로직
4. 상품가격변경
	재고변경과 유사한 로직
5. 상품삭제
	PK입력받기
	if(올바른 번호면 진행)
	else(올바르지 않으면 진행... == selectOne의 output이 없음 == null)
	사용자가 누굴 삭제할지 입력
	controller가 있는지 없는지 check해줌
	없으면 다시 위로
	있으면 삭제 진행

 

Code

Client

package client;

import controller.Ctrl;

public class Test {
	
	Ctrl app = new Ctrl();
	app.start();
	
}

 

ProductDTO

package model;

public class ProductDTO {

	private int pkNum;
	private String name;
	private int price;
	private int cnt;

	private String searchCondition;
	private int addCnt;

	public int getPkNum() {
		return pkNum;
	}

	public void setPkNum(int pkNum) {
		this.pkNum = pkNum;
	}

	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;
	}

	public String getSearchCondition() {
		return searchCondition;
	}

	public void setSearchCondition(String searchCondition) {
		this.searchCondition = searchCondition;
	}

	public int getAddCnt() {
		return addCnt;
	}

	public void setAddCnt(int addCnt) {
		this.addCnt = addCnt;
	}

	@Override
	public String toString() {
		return "[" + this.pkNum + "]" + this.name + "가격: " + this.price + ", 재고: " + this.cnt;
	}

}

 

ProductDAO

package model;

import java.util.ArrayList;

public class ProductDAO {

	ArrayList<ProductDTO> datas;

	public ProductDAO() {
		this.datas = new ArrayList<ProductDTO>();
		// sample
		ProductDTO sample01 = new ProductDTO();
		sample01.setPkNum(1001);
		sample01.setName("콜라");
		sample01.setPrice(1500);
		sample01.setCnt(3);
		datas.add(sample01);
		ProductDTO sample02 = new ProductDTO();
		sample02.setPkNum(1002);
		sample02.setName("사이다");
		sample02.setPrice(1500);
		sample02.setCnt(2);
		datas.add(sample02);
	}

	// R - 전체출력
	public ArrayList<ProductDTO> selectAll(ProductDTO productDTO) {
		// 전체검색
		if (productDTO.getSearchCondition() == null) {
			return this.datas;
		}
		// 이름검색
		else if (productDTO.getSearchCondition().equals("이름검색")) {
			ArrayList<ProductDTO> searchDatas = new ArrayList<ProductDTO>();
			for (int i = 0; i < this.datas.size(); i++) {
				if (this.datas.get(i).getName().contains(productDTO.getName())) {
					searchDatas.add(this.datas.get(i));
				}
			}
			return searchDatas;
		}
		return null;
	}

	// R - 하나출력
	public ProductDTO selectOne(ProductDTO productDTO) {
		boolean flag = false;
		int i;
		for (i = 0; i < this.datas.size(); i++) {
			if (productDTO.getPkNum() == this.datas.get(i).getPkNum()) {
				flag = true;
				break;
			}
		}
		if (!flag) {
			return null;
		}
		return this.datas.get(i);
	}

	// C
	public boolean insert(ProductDTO productDTO) {
		try {
			ProductDTO data = new ProductDTO();
			data.setPkNum(productDTO.getPkNum());
			data.setName(productDTO.getName());
			data.setPrice(productDTO.getPrice());
			data.setCnt(productDTO.getCnt());
			this.datas.add(data);
		} catch (Exception e) {
			System.out.println("[로--그] 알수없는오류 발생!");
			return false;
		}
		return true;
	}

	// U
	public boolean update(ProductDTO productDTO) {
		// 구매 - 재고 1개 차감
		if (productDTO.getSearchCondition().equals("구매")) {
			// 인자로 받아온 객체의 재고에서 -1을 해준 값을 이 객체의 재고에 저장
			productDTO.setCnt(productDTO.getCnt() - 1);
		}
		// 가격변경 - 인자로 받아온 객체의 가격으로 변경
		else if (productDTO.getSearchCondition().equals("가격변경")) {
			// 인자로 받아온 객체의 가격을 이 객체의 가격에 저장??????
			productDTO.setPrice(productDTO.getPrice());
		}
		// 재고변경 - 인자로 받아온 객체의 재고로 변경
		else if (productDTO.getSearchCondition().equals("재고변경")) {
			// 인자로 받아온 객체의 재고를 이 객체의 재고에 저장??????
			productDTO.setCnt(productDTO.getCnt());
		}
		// 재고추가 - 인자로 받아온 객체의 재고를 추가
		else if (productDTO.getSearchCondition().equals("재고추가")) {
			// 인자로 받아온 객체의 기존재고 + add재고를 이 객체의 재고에 저장
			productDTO.setCnt(productDTO.getCnt() + productDTO.getAddCnt());
		} else {
			return false;
		}
		return true;
	}

	// D
	public boolean delete(ProductDTO productDTO) {
		try {
			boolean flag = false;
			int i;
			for (i = 0; i < this.datas.size(); i++) {
				if (productDTO.getPkNum() == this.datas.get(i).getPkNum()) {
					flag = true;
					break;
				}
			}
			this.datas.remove(i);
		} catch (Exception e) {
			System.out.println("[로--그] 알수없는오류 발생!");
			return false;
		}
		return true;
	}
}

 

View

package view;

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

import model.ProductDTO;

public class View {

	private Scanner sc;

	public View() {
		this.sc = new Scanner(System.in);
	}

	public void printMenu() {
		System.out.println("=== 자 판 기 ===");
		System.out.println("1. 상품목록출력");
		System.out.println("2. 상품선택");
		System.out.println("3. 이름으로검색");
		System.out.println("0. 종료");
	}

	public int inputInteger() {
		System.out.print("번호입력 >> ");
		int integer = sc.nextInt();
		return integer;
	}

	public void printAdminMenu() {
		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("0. 관리자모드 종료");
	}

	public int inputpkNum() {
		System.out.print("상품번호입력 >> ");
		int pkNum = sc.nextInt();
		return pkNum;
	}

	public String inputName() {
		System.out.print("상품이름입력 >> ");
		String name = sc.next();
		return name;
	}

	public int inputPrice() {
		System.out.print("상품가격입력 >> ");
		int price = sc.nextInt();
		return price;
	}

	public int inputCnt() {
		System.out.print("상품재고입력 >> ");
		int cnt = sc.nextInt();
		return cnt;
	}

	public void printTrue() {
		System.out.println("성공!");
	}
	
	public void printFalse() {
		System.out.println("실패!");
	}

	public void printInsertData(ProductDTO productDTO) {
		System.out.println(productDTO.getName() + "데이터 추가");
	}

	public void printDatas(ArrayList<ProductDTO> datas) {
		if (datas.size() == 0) {
			System.out.println("데이터 없음...");
		}
		for (ProductDTO data : datas) {
			if (data.getCnt() == 0) {
				System.out.println(data.getName() + "재고 없음...");
				continue;
			}
			System.out.println(data);
		}
	}
	
	public void printData(ProductDTO productDTO) {
		if(productDTO == null) {
			System.out.println("일치하는 데이터가 없습니다.");
			return; //메소드 종료 
		}
		if(productDTO.getCnt() == 0) {
			System.out.println("재고가 없습니다.");
			return; //메소드 종료
		}
		System.out.println(productDTO);
		System.out.println("구매완료");
	}
	
	public void printNoData() {
		System.out.println("데이터 없음....");
	}

}

 

Controller

package controller;

import java.util.ArrayList;

import model.ProductDAO;
import model.ProductDTO;
import view.View;

public class Ctrl {

	private ProductDAO productDAO;
	private View view;
	private int PK;
	
	public Ctrl() {
		this.productDAO = new ProductDAO();
		this.view = new View();
		this.PK = 1003;
	}
	
	public void start() {
		while(true) {
			view.printMenu();
			int action = view.inputInteger();
			if(action == 0) {
				break;
			}
			//관리자모드
			else if(action == 7777) {
				while(true) {
					view.printAdminMenu();
					action = view.inputInteger();
					if(action == 0) {
						break;
					}
					//상품추가
					else if(action == 1) {
						//추가할 상품의 이름, 가격, 재고 사용자에게 받기 view
						String name = view.inputName();
						int price = view.inputPrice();
						int cnt = view.inputCnt();
						//new객체 생성해서 값들 저장 set
						ProductDTO productDTO = new ProductDTO();
						productDTO.setPkNum(PK++); //PK번호는 ++
						productDTO.setName(name);
						productDTO.setPrice(price);
						productDTO.setCnt(cnt);
						//new객체를 inser() input! model
						productDAO.insert(productDTO);
					}
					//상품가격변경
					else if(action == 2) {
						//사용자가 변경할 상품 선택 view
						int pkNum = view.inputpkNum();
						//PK, 가격을 new 객체에 저장
						ProductDTO productDTO = new ProductDTO();
						productDTO.setPkNum(pkNum);
						//model이 selectOne()로 이 객체를 찾아줄거임
						productDTO = productDAO.selectOne(productDTO);
						if(productDTO == null) {
							view.printNoData();
							continue;
						}
						//변경할 가격 입력 view
						int price = view.inputPrice();
						productDTO.setPrice(price);
						productDTO.setSearchCondition("가격변경");
						//update()로 가격을 변경해줌
						boolean flag = productDAO.update(productDTO);
						if(flag) {
							view.printTrue(); //update성공!
						}
						else {
							view.printTrue(); //update실패!
						}
					}
					//상품재고변경
					else if(action == 3) {
						//사용자한테 재고변경할 상품물어보기 view
						int pkNum = view.inputpkNum();
						//new 객체 생성
						ProductDTO productDTO = new ProductDTO();
						productDTO.setPkNum(pkNum);
						//배열에 pk번호 일치하는 객체 찾기
						productDTO = productDAO.selectOne(productDTO);
						//혹시 찾은 객체가 없으면
						if(productDTO == null) {
							view.printNoData();
							continue;
						}
						//사용자한테 변경할 재고 받기
						int cnt = view.inputCnt();
						productDTO.setCnt(cnt);
						//update()에서 재고변경을선택할 거니까
						productDTO.setSearchCondition("재고변경");
						//model로 재고 업데이트 해주기
						boolean flag = productDAO.update(productDTO);
						if(flag) {
							view.printTrue(); //update성공!
						}
						else {
							view.printTrue(); //update실패!
						}
					}
					//상품재고추가
					else if(action == 4) {
						//어떤상품 추가할래? 관리자에게 PK받기 view
						int pkNum = view.inputpkNum();
						//새로운 객체 생성해서 pkNum set
						ProductDTO productDTO = new ProductDTO();
						productDTO.setPkNum(pkNum);
						//selectOne으로 일치하는 객체 찾기
						productDTO = productDAO.selectOne(productDTO);
						//만약 그 객체가 비었다면 view로 없다해줘
						if(productDTO == null) {
							view.printNoData();
							continue; //다시 while문 처음으로 가
						}
						//있으면 관리자에게 추가할 재고 받기 view
						int addCnt = view.inputCnt();
						productDTO.setAddCnt(addCnt);
						productDTO.setSearchCondition("재고추가");
						//model로 재고update해줘
						boolean flag = productDAO.update(productDTO);
						if(flag) {
							view.printTrue(); //update성공!
						}
						else {
							view.printTrue(); //update실패!
						}
					}
					//상품삭제
					else if(action == 5) {
						//어떤상품 삭제할래? 관리자에게 PK받기 view
						int pkNum = view.inputpkNum();
						//새로운 객체 생성해서 pkNum set
						ProductDTO productDTO = new ProductDTO();
						productDTO.setPkNum(pkNum);
						//selectOne으로 일치하는 객체 찾기
						productDTO = productDAO.selectOne(productDTO);
						//만약 그 객체가 없다면 view로 없다해줘
						if(productDTO == null) {
							view.printNoData();
							continue;
						}
						//있으면 model로 상품삭제
						boolean flag = productDAO.delete(productDTO);
						if(flag) {
							view.printTrue(); //delete성공!
						}
						else {
							view.printFalse(); //delete실패!
						}
					}
				}
			}
			//상품목록출력
			else if(action == 1) {
				//new 객체 생성해서 selectAll로 전체 출력
				ProductDTO productDTO = new ProductDTO();
				//배열에 추가
				ArrayList<ProductDTO> datas = productDAO.selectAll(productDTO);
				//view로 전체목록 출력
				view.printDatas(datas);
			}
			//상품선택
			else if(action == 2) {
				//사용자에게 상품PK 받아오기
				int pkNum = view.inputpkNum();
				//new객체에 PK 저장
				ProductDTO productDTO = new ProductDTO();
				productDTO.setPkNum(pkNum);
				//selectOne으로 일치하는 상품 찾기
				ProductDTO data = productDAO.selectOne(productDTO);
				//상품 없는 경우, 재고 없는 경우, 구매 가능한 경우
				//사용자에게 상태를 알려주기 위해 view로 출력
				view.printData(data);
				//관리자 입장에서 구매를하면 재고가 빠져야하니,
				//상품이 존재하고 재고가 있으면 구매 성공!
				boolean flag = false;
				if(data != null && productDTO.getCnt() > 0) {
					data.setSearchCondition("구매");
					flag = productDAO.update(data);
				}
				if(flag) {
					view.printTrue();
				}
				else {
					view.printFalse();
				}
			}
			//이름으로검색
			else if(action == 3) {
				//사용자에게 검색할 이름 받기 view
				String name = view.inputName();
				//new 객체 생성해서 이름, searchConditoin 저장
				ProductDTO productDTO = new ProductDTO();
				productDTO.setName(name);
				productDTO.setSearchCondition("이름검색");
				//중복되는 이름이 있을 수 있으니 selectAll로 출력
				ArrayList<ProductDTO> datas = productDAO.selectAll(productDTO);
				//아무 데이터가 없으면 데이터 없다하고 다시 위로
				if(datas == null) {
					view.printNoData();
					continue;
				}
				//view로 출력
				view.printDatas(datas);
			}
		}
	}
}