필수 기능 2번 보완, 도전 기능 3번, 4번 구현 및 readme 작성
Shoppingmall(){
// 금액 총합
totalCost=0;
//상품 객체 생성
var shirts=Product('shirts', 45000);
var dress=Product('dress',30000);
.
.
.
// 상품 목록 Map에 투입
productMap.addAll({...});
}
어제 코드에서 터미널이 입력하는 한글을 제대로 인식하지 못하는 오류가 있었는데, 결국 해결이 안 되어서 상품명을 영문으로 지정하였다.
while(keepAdd){
// 상품명 입력받기
print('상품명을 입력해주세요. 영문자만 지원합니다.');
productName=stdin.readLineSync(/*encoding: Encoding.getByName('utf-8')!*/)!;
// 사용자가 exit를 입력했을 시 장바구니에 담는 기능을 종료
if(productName=='exit'){
break;
}
// productMap에 물건 이름과 일치하는 key가 없을 경우
else if(!productMap.containsKey(productName)){
print('존재하지 않는 상품입니다. 취소를 원하시면 [exit]를 입력해주세요.');
continue;
}
// 상품 수량 입력받기
try{
print('수량을 입력해주세요.');
productAmount=int.parse(stdin.readLineSync().toString());
// 수량을 0 이하로 입력한 경우 InputException 발생
if(productAmount<=0){throw InputException(null);}
}on InputException{
print('0개보다 많은 개수의 상품만 담을 수 있어요!');
continue;
// 입력값이 정수 형태가 아닌 경우 에러 메시지 출력
}catch(e){
print('입력값이 올바르지 않습니다!');
continue;
}
keepAdd=false;
}
exit
기능은 테스트하는 과정에서 while
문이 끝나지 않을 때 메인 메뉴로 탈출하기 위해 임시로 만들었는데, 만들어두고 보니 그냥 둬도 쓸만할 것 같아서 최종 버전에서도 삭제하지 않았다.
// 상품명과 가격이 모두 옳게 입력되었을 경우에 총 금액 업데이트
if(productName!=null&&productAmount!=null){
//productMap[productName] : 물건 가격
totalCost+=productMap[productName]!*productAmount!;
print('장바구니에 상품이 담겼어요 ! ');
}
else{
print('장바구니를 종료합니다.');
}
하지만 exit
명령어로 탈출하면 상품명 또는 수량을 입력받는 과정을 건너뛰어 productName
또는 productAmout
가 null
값으로 남는 경우가 있기 때문에 위처럼 분기를 나눠서 처리해주었다.
장바구니에 담을 상품 목록을 List
로 표현할 수도 있지만, 이후에 장바구니에 담은 각 상품의 개수를 표현하는 기능을 넣을 예정이기 때문에 key
와 value
를 각각 저장하는 Map
으로 만들었다.
// <장바구니에 담긴 상품 이름, 개수>
Map<String?, int?> cartMap={};
또한 addToCart()
함수에 새 객체를 Map
에 넣는 다음 코드를 추가하였다.
// 새로 장바구니에 담는 상품이면 Map에 추가한다.
if(!cartMap.containsKey(productName)){
cartMap[productName]=productAmount;
// 이미 담은 적 있던 상품이면 value인 개수만 수정한다.
} else {
cartMap[productName]=productAmount+cartMap[productName]!;
}
이제 상품 목록을 열람하는 기능을 만들어보자.
원래 상품의 총 금액을 보여주는 기능을 하던 showTotal()
함수를 수정했다.
void showTotal(){
if(cartMap.isEmpty){
print('장바구니에 담긴 상품이 없습니다.');
}
else{
print('장바구니에 담긴 상품은\n');
for(var entry in cartMap.entries){
print('${entry.key}: ${entry.value}\n');
}
print('입니다. 총 $totalCost원 입니다.\n');
}
}
cartMap
안의 정보를 key
, value
순서대로 편하게 출력할 수 있는 방법이 무엇이 있을지 찾아보니 entry
를 사용하면 key
와 value
를 한 객체 안에 묶을 수 있다고 한다. for-in 순회를 통해 상품과 각각의 가격을 출력하도록 하였다.
현재까지 과제 내용 외에 추가한 기능은 장바구니에 담다가 중간에 취소하는 기능, 장바구니에 담긴 상품의 개수를 저장하는 기능이다. 이제 상품 개수를 바탕으로 장바구니에서 원하는 물건을 지우는 기능을 구현해보겠다.
원래 '장바구니 초기화'였던 6번 메뉴를 '장바구니 편집'으로 변경한다. 또한 원래 6번 메뉴에 연결되어있던 resetTotalCost()
함수의 이름을 조금 더 쓰임새에 맞게 resetCart()
로 바꿔주었다.
resetCart()
에서는
[1] 장바구니 초기화 / [2] 선택 상품만 삭제
두 가지 기능을 지원하는데 case
문을 이용해서 분기를 나눠주었다. 선택 상품을 삭제하는 부분에서는 상품명과 삭제하고 싶은 수량을 입력받는다. 수량을 입력받는 부분만 예시로 보자.
try{
print('삭제할 상품의 수량을 입력해주세요.\n');
amountToDelete=int.parse(stdin.readLineSync()!);
// 담은 상품 양보다 많이 삭제하려고 할 경우
if(cartMap[productToDelete]!<amountToDelete){
throw InputException(null);}
}on InputException{
print('0개 이하로 삭제할 수 없습니다.\n');
continue;
}catch(e){
print('입력값이 잘못되었습니다!\n');
continue;
}
이 때 담은 상품보다 많이 삭제할 수는 없기 때문에 예외 처리를 해주었다.
이후에는 장바구니 컬렉션인 cartMap
에서 수량을 조절해주고, 해당 상품을 전부 삭제하는 경우 아예 key
값 자체를 뺀다. 금액 총합까지 조절하고 나면 장바구니 편집이 완료된다.
// 수량 조절
cartMap[productToDelete]=cartMap[productToDelete]!-amountToDelete;
// 금액 총합 조절
totalCost-=productMap[productToDelete]!*amountToDelete;
// 특정 물건을 0개로 만들었을 경우 Map에서 삭제
if(cartMap[productToDelete]==0){cartMap.remove(productToDelete);}
print('삭제를 완료했습니다.\n');
실행 화면
할 일 목록
필수 기능 1번 : 판매하는 상품 목록
필수 기능 2번 : 상품을 장바구니에 추가
필수 기능 3번 : 금액 총합 출력
필수 기능 4번 : 프로그램 종료
도전 기능 1번 : 프로그램을 종료할지 한 번 더 묻는 기능
도전 기능 2번 : 장바구니 초기화
도전 기능 3번 : 장바구니 상품 목록+금액 총합 출력
도전 기능 4번 : 자유롭게 기능 추가(상품 개수 출력, 선택 삭제 기능)