<< 목차 >>
* 프로젝트 깃허브 레포지토리 주소
* 최종 클래스 다이어그램
* 기능 소개
* 문제와 해결
* 느낀 점
프로젝트 깃허브 레포지토리
GitHub - JisooPyo/MakeKiosk
Contribute to JisooPyo/MakeKiosk development by creating an account on GitHub.
github.com
클래스 다이어그램
기능 소개
Main
키오스크를 실행시키는 실행 클래스
Kiosk
onKiosk() → 키오스크를 켠다 -> menuScreen() 메서드 실행
menuScreen() → menu 화면. 번호를 선택하면 번호에 따라서 다른 화면으로 전환.
1~4. productScreen() → 상품 화면
5. orderScreen() → 주문 화면
6. cancelScreen() → 취소 화면
7. offKiosk() → 키오스크를 끈다.
0. totalSalesScreen() → 총 판매 금액 / 목록 을 보여주는 화면
ProductDB
메뉴와 상품에 관한 메뉴명, 가격, 설명, 옵션이 저장되어 있다.
Menu
showMenu()
menu를 출력해준다. 아래 사진이 showMenu()를 했을 때 출력되는 부분.
menuPartLength( List<Menu> ) : int
Menu List를 input으로 받으면 메뉴 부분의 길이를 출력해준다.
makeList( List<Menu> )
Menu List를 받으면 리스트로 출력해 준다. 아래 사진의 1번부터 4번까지의 리스트가 이 메서드를 이용하여 만든 리스트이다.
Product
showProduct( int )
int에 따라서 상품 화면을 출력해준다. 아래는 1번을 선택했을 때 나오는 Burger 메뉴
menuPartLength ( List<Product> ) : int → Menu클래스에 있는 같은 이름의 메소드와 기능이 같다.
makeList( List<Product> ) → Menu클래스에 있는 같은 이름의 메소드와 기능이 같다.
pickProduct( int, int ) : Product
첫번째, 두번째 입력했던 숫자를 기반으로 상품을 골랐을 때 나오는 화면 구현.
ex. 1, 1 -> burgers - ShackBurger
옵션이 있다면 어떤 옵션으로 추가할 것인지 물어보고, 옵션이 없다면 바로 메뉴를 장바구니에 추가할 것인지 물어본다. 그 후 장바구니에 추가할 상품을 리턴해준다.
Order
showOrder()
장바구니의 목록을 보여준다.
getSum( List< Product > ) : double
List를 input으로 받아 가격 총값을 더해준다.
addOrder( Product )
장바구니에 추가하는 메서드, Product의 클래스에서 pickProduct 메서드를 하여 리턴한 Product는 여기로 들어와서 Order 클래스의 List< Product > orderList 에 저장을 해준다.
makeList( List< Product > ) → Menu클래스에 있는 같은 이름의 메소드와 기능이 같다.
makeList( List< Product > ) : List< Product >
List를 input으로 받아 sout해주는 메서드
addCount( Product )
상품을 받아서 countMap(K: 상품, V: 개수인 Map)에서 그 상품에 맞는 value값을 찾아 갯수를 더하기 1해주는 메서드
문제와 해결
1. 구조의 꼬임
데이터가 메뉴 클래스에서 상품 클래스로 상품 클래스에서 주문 클래스로 넘어 갈 때, 어떤 식으로 데이터를 넘겨 줘야 하는 건지, return을 이용한다면 return에 뭘 줘야 하는지, 여러 개를 넘겨 줘야 한다면 어떻게 넘겨 줄 것인지 구조가 떠오르지 않아서 연속 상속으로 데이터를 받아 오려다가 마지막 주문 클래스에서 다시 메뉴 클래스로 돌아갈 때 데이터를 넘기지 못해서 구조가 꼬여 버려 아예 코드를 새로 짜게 되었다.
※ 튜터님 조언 - 코드를 짤 때 응집도는 높게, 결합도는 낮게 해야 하는데 상속은 결합도를 아주 강하게 높이는 것이므로 많이 쓰지 않는것이 좋다고 하셨다.
2. 데이터 수정의 어려움
상속을 쓰지 않고 데이터를 꺼내 쓰려다 보니 메뉴, 상품의 정보들이 들어 있어 DB역할을 하는 ProductDB 클래스를 만들게 되었다. 데이터를 빼고 따로 저장해 놓고 쓰는 것이 아니라 데이터가 필요할 때마다 DB에서 데이터를 꺼내써서 중간에 데이터를 수정하고자 하는게 어려웠다. 데이터를 꺼내서 쓸 때마다 첫 번째 ,두 번째 선택했던 int 두 개 가지고 스위치 문을 계속 쓰면서 데이터를 DB에서 뽑아왔기 때문에 코드가 길어졌다.
데이터를 꺼내서 쓰는 게 아니라 꺼낸 데이터를 저장하자! 라는 생각이 들어서 스트링 배열을 하나 만들어 거기에다가 카트에 넣을 상품의 특성을 저장하고, 이를 List< String[] > 에 담아 장바구니를 구현하였다.
스트링 배열로 저장을 하니 코드가 너무 난잡해지는 거 같아서 Product를 새로 만들어 그 Product를 넘기는 데이터로써 활용하였다.
3. 필요한 메서드의 구현
장바구니에서 겹치는 물건의 개수를 세어주는 옵션에서 List< String[] > 내에 String[]가 포함되어 있는지 여부를 확인하는 작업이 필요하였는데
사진과 같이 값이 같은 배열이 포함되어 있나요? 하고 contains() 메서드를 이용하면 false가 return된다. contain은 주소값이 같은 애가 있는지 찾기 때문에 안 되는 것이었다. 따라서 내가 원하는 contain 메서드를 직접 구현해야 했다.
public boolean containStrArr( List< String[] > list, String[] strArr ) {
boolean containStrArr = false;
for ( int i = 0 ; i < list.size() ; i++ ) {
if ( Arrays.equals( list.get( i ), strArr ) ) {
containStrArr = true;
break;
}
}
return containStrArr;
}
// list에 strArr과 같은 값이 있는지를 판단하여 boolean으로 return해주는 메서드
4. ProductDB 클래스의 구조 변경
DB 클래스를 만들 때 원래는 한 상품 한 메뉴마다 static 을 써서 stackOverflow 오류가 일어나지 않고, 다른 클래스에서 바로 쓸 수 있도록 하였는데 static을 너무 남발하는 것도 좋지 않아 보여 구조를 바꿔봐야겠다고 생각했다.
기존 클래스에서 전역 변수, static으로 선언했던 Product들을 메서드에 넣어서 Product[]를 리턴하는 메서드 안에 넣어서 구조를 바꿔 보았다. Menu와 Product도 Map으로 엮어 주었다. 이로 인해 기존에 있던 긴 스위치 문을 아예 없앨 수 있었다. 지금은 배열이 아니라 List에 저장할 수 있도록 바꾸어 놓았다.
private List< Product > burgerList() {
Product burger1 = new Product( "ShackBurger", "토마토, 양상추, 쉑소스가 토핑된 치즈버거", "Single", 6.9, "Double", 10.9 );
Product burger2 = new Product( "SmokeShack", "베이컨, 체리 페퍼에 쉑소스가 토핑된 치즈버거", "Single", 8.9, "Double", 12.9 );
...
List< Product > burgerList = new ArrayList<>();
burgerList.add( burger1 );
burgerList.add( burger2 );
...
return burgerList;
}
private List< Product > frozenCustardList() {
Product frozenCustard1 = new Product( "Shakes", "바닐라, 초콜렛, 솔티드 카라멜, 블랙 & 화이트, 스트로베리, 피넛버터, 커피", "oneSize", 5.9 );
Product frozenCustard2 = new Product( "Shake of the Week", "특별한 커스터드 플레이버", "oneSize", 6.5 );
...
return frozenCustardList;
}
public Map< String, List< Product > > menuMap() {
List< Menu > menuList = menuList();
Map< String, List< Product > > menuMap = new HashMap<>();
menuMap.put( menuList.get( 0 ).name, burgerList() );
...
return menuMap;
}
5. 주석 추가의 필요성
내 코드를 팀원에게 설명하는 일이 있었는데 긴장이 되어서 제대로 설명하지 못했던 것 같다. 주석이 있었다면 팀원도 이해하기 편하고 나도 설명하기 좀 더 편했을 것 같다. 주석을 남겨 놓으면 내가 나중에 보더라도 아 이런 구조로 내가 구현했었구나 하고 잘 알 수 있을 것이다. 그래서 모든 메서드와 중간중간 필요하다고 느껴지는 부분에 주석을 추가해서 다시 push했다.
느낀 점
이렇게 구조적으로 정리가 되고 나니까 주문한 데이터의 수정과 사용이 편해졌고 개선을 할 때에도 적은 수정으로 빠르게 개선이 가능하였다. 옵션을 고르는 기능, 전체 판매한 상품들의 리스트와 총 판매 가격을 보여주는 기능, 대기번호 기능을 추가하고 메서드를 더 관련 있는 클래스로 옮겨서 응집도를 높였다.
과제 제출 이후에도 전달할 데이터를 String배열에 저장하는 방식을 Product를 넘겨 주는 방식으로 바꾸어 Order 클래스에 있는 메서드도 7개에서 5개로 줄일 수 있었다. 주석도 추가하여 모르는 사람이 보더라도, 내가 나중에 보더라도 어떤 구조로 키오스크를 구현했는지 보기 쉽게 해놓았다.
깃 커밋할 때에도 코드가 변할 때마다 내가 뭘 했는지 자세히 남겨놓으니 어떤 식으로 코드가 개선되어지는지 알기 쉽게 볼 수 있어서 깃 커밋을 앞으로 좀 더 잘 써야겠다고 생각했다.
이런 구현은 처음이고 객체에 대한 내용 이해도 잘 안 되어 있는 상황에서 구현하는게 힘들었지만 그만큼 더 객체에 대한 이해가 빨리 와닿았던 과제이기도 하고 많은 것을 배울 수 있었던 과제였다.
'SPARTA Project' 카테고리의 다른 글
[Java] HI5조 - 호텔 예약 프로그램 프로젝트 (6/6 - 6/9) (1) | 2023.06.07 |
---|---|
[Java] HI5조 - 메모장 프로젝트 (6/2 - 6/5) (0) | 2023.06.05 |
< 초록색이 젤다 맞죠? > - KPT 회고 (0) | 2023.05.19 |
< 초록색이 젤다 맞죠? > - 팀 프로젝트 04 (1) | 2023.05.18 |
< 초록색이 젤다 맞죠? > - 팀 프로젝트 03 (0) | 2023.05.17 |