JAVA Day-7(예매시스템)

영화관 예매 시스템

이번에는 영화관 예매시스템을 만들어 보면서 while과 switch문을 좀더 디테일하게 익히고 추가적으로 JOptionPane도 사용해보면서 view단을 좀더 직관적으로 살펴보자

영화관 예매시스템만들기

우리가 문화생활로 손에 꼽는 곳 하나인 영화관은 점차 비대면 시스템으로 바뀌고 있으며 이제는 비대면으로 당연하게 사용하고 있다.
물론 영화관에서 사용하는 예매시스템과 같이 다이나믹하게 꾸미지는 못하지만 주요기능들을 만들어 볼 것이다.
우리는 지금까지 배운 코드로만 작성하기때문에 기능적인 한계가 분명 존재하며 기본적인 API와 같은 서버통신을 하지 않는 축소화된 기능으로 배운 코드를 응용한다는 생각으로 작성하면 될 것 같다.

현업에서 작성되는 코드라고 하지만 극히 일부분이니 작성간 사고의 흐름과 지금까지 배운 코드를 작성하는 것에 대한 연습을 중점으로 생각하자.

영화관 예매시스템에 들어갈 기능과 코드

주요 기능

먼저 우리가 작성 할 영화관 예매시스템의 주요 기능은 다음과 같다.
1. 최초 타이틀 화면에서의 환영문구
2. 예매하기, 구매하기, 포인트조회, 나가기
3. 영화의 종류, 영화의 관람 등급 (성인만 구분)
4. 스낵의 종류, 음주류만 구매 연령 확인
5. 포인트가 많을 시에는 포인트 먼저 결재되고 다음 현금이 결재되도록 하기

주요 코드

1.JOptionPane.show~~ 이제 콘솔창이 아닌 다른 방식을 사용함.
2. while(true) 예매가 완료 후 다음 메뉴를 선택하기 위해 반복으로 띄움
3. switch 기능을 단락으로 구분 가능할때 사용함, 여기에서는 예매~나가기까지 구분하여 선택 할 수 있음으로 case로 나눔
4. if조건문. 예매가 완료되면 포인트와 현금을 차감하는 기능 구현
혹은 나이가 19세 이상만 청소년 구매 불가 상품 구매가능 기능 구현
5. 변수의 타입 String, int, boolean을 사용하였다.

주의사항
여기서 사용하는 것은 아직 배열과 클래스를 배우기 이전이기에 배열, 클래스 생성, 메서드 정의를 제외하고 위에서 주요코드에 작성한 코드로만 기능을 간단하게 구현 할 것이다.

작성해보기

위에서 작성하고 만들 작품을 생각해보았으니 만들어보자

메인클래스 안에서 전부 작성할 것임으로 메인메소드 바디 밖과 메인메소드 자체는 생략한다.

  1. 먼저 최초 화면에 나오는 장면은 환영문구가 나오는 장면이다. 간단하게 JOptionPane.showMessage로 표현이 가능하겠다. 우리는 변수도 배웠으니 환영문구를 변수로 만들어 표현해보자 (보통 변수에 저장공간을 할당하는 이유는 변수를 지정하여 재사용하기 위함임.)
String helloMsg  = "어서오세요 CGV입니다.\n";
JOptionPane.showMessageDialog(helloMsg);
  1. 다음은 화면이 전환되면 예약, 구매, 포인트조회, 나가기가 나와야 하지만 여기서 배열과 showOption은 사용하지 않을 것이기에 문자열을 담아 사용하겠다. 따라서 입력을 받아야됨으로 input으로 바꾸고 menuMsg도 추가하자
String helloMsg  = "어서오세요 CGV입니다.\n";
String menuMsg = "①예매하기\n②구매하기\n③포인트조회\n④나가기\n";
JOptionPane.showInputDialog(helloMsg+menuMsg)
  1. 실제로 버튼이 동작하는 것은 아니지만 이처럼 직관적으로 표현하여 사용자가 직접 입력하게 만드는 것도 괜찮을 것 같다.
    예매하기나 포인트조회를 할 수 있도록 while구문으로 반복시키자
    또한 변수들은 반복문 밖에서 사용하면 되겠다.
String helloMsg  = "어서오세요 CGV입니다.\n";
String menuMsg = "①예매하기\n②구매하기\n③포인트조회\n④나가기\n";

while(ture){
  JOptionPane.showInputDialog(helloMsg+menuMsg)
}
  1. 먼저 화면에서 나가기, 그리고 1~3까지 제외한 숫자를 입력 시 막아주는 코드를 작성하자, if문으로 참일때로 표현하면 되겠다.
생략.....
while(ture){
//입력 받은 숫자를 담을 공간이 없음. 
  JOptionPane.showInputDialog(helloMsg+menuMsg)
}

작성하려보니 최초 input을 담을 공간이 없는 것을 확일 할 수 있다.
따라서 input을 담을 공간인 choice(변수명)을 만들어보자
정수를 입력받아야 되니 정수형태로 만들어야 겠다.

생략.....
int choice = 0; 
while(ture){
 choice = JOptionPane.showInputDialog(helloMsg+menuMsg)
}

choice 부분에 오류가 생기는데 이는 inputDialog의 매개변수가 문자열이기 때문에 type오류가 생긴다. 그래서 정수형으로 강제변환시켜 정수로 입력 받아야 된다.
정수형으로 변환하는 코드는 Integer.parseInt이다.

생략.....
int choice = 0; 
while(ture){
 choice = Integer.parseInt(JOptionPane.showInputDialog(helloMsg+menuMsg))
}

이제 choice에 정수를 입력 받을 수 있으니 조건식을 걸어 나가기와 1~3을 제외한 나머지 숫자를 입력을 막아보자

생략.....
int choice = 0; 
while(ture){
if(choice == 4) break;
if(!(choice >= 1 && choice <= 3)) continue;
생략....
}

조건식에 !가 있으면 반대를 말한다. 1보다 크고 3보다 작을때가 아닐때가 되는 것임.

  1. 이제 각 1~3을 입력 받을때 코드를 작성해보자 간단한 값을 입력받을 수 있으니 switch로 표현하는 것도 괜찮겠다.
    choice에 입력되는 값은 숫자이니 switch에도 숫자를 받아오자
생략....
choice = Integer.par....
if(choice == 4) break;
if(!(choice >= 1 && choice <= 3)) continue;
switch(choice){
//예매하기 영역
case 1 : 
	break;
//구매하기 영역
case 2 : 
	break;
//포인트조회 영역
case 3 : 
	break;
}
  1. 위 처럼 각 case가 무엇을 말하는지 주석처리하여 협업에 도움을 주자
    먼저 case 1의 내용부터 작성해보자 예매하기 영역은 영화의 종류를 선택하고 그 영화에 따라 예매가 되는 기능을 만들어야 한다. 여기서는 간단하게 영화가 예매되었는지 여부를 메시지로 출력하고 돈이 빠져나가는 구조만 만들어 본다.
    어떤 영화가 있는지 보여주면 되겠다.
    마찬가지로 choice를 사용할 것인데 방금 사용한 choice는 case 1에서 사용하지 않기에 다시 덮어써도 되겠다.(어차피 메뉴에서 사용하면 그때 다시 덮어씌여저서 괜찮음)
    또한 작성하려보니 영화종류가 많음으로 변수로 사용하자(배열을 배우면 보통 배열을 사용함.
생략.... 
String menuMsg = "①예매하기.......
tring films = "①라이언킹(0800)\n②스파이더맨(1200)\n③사일런스(2300)[청소년 관람 불가]\n④뒤로가기\n";
생략...
    case 1 : 
    choice = Integer.parseInt(JOptionPane.showInputDialog(films));
  1. 이제 영화를 선택하면 나오는 메시지를 각각 만들어 보자
    청소년 관람불가는 나이가 19세 이상일때 구매가 되어야 하는데 그럼 age도 입력하게 만들고 age만의 변수도 따로 만들어야 겠다.
String menuMsg = "①예매하기....
......
int age = 0;
생략...
   case 1 : 
    choice = Inte......
    	if(choice == 1) {
        	JOptionPane.showMessageDialog(null, "라이언킹 예매 완료(0800)");
		} else if(choice == 2) {
		JOptionPane.showMessageDialog(null, "스파이더맨 예매 완료(1200)");	
		}else if(choice == 3) {
		age = Integer.parseInt(JOptionPane.showInputDialog(ageMsg));
			if(age > 19) {
			JOptionPane.showMessageDialog(null, "사일런스 예매 완료(2300)");					
			}else {
			JOptionPane.showMessageDialog(null, "다시 시도해 주세요");	
			}
		}else {
		JOptionPane.showMessageDialog(null, "메인 메뉴로 이동합니다.");
		continue;
		}
age도 정수로 변환시켜 값을 받앗으며 age가 만족 하지 않으면 메시지를 별도로 띄웠다. 
  1. 이제 간단한 입력을 하면 예매완료랑 메인 메뉴까지 간단하게 표현하는 것을 만들어 보았다. 현업에서 가장 중요하는 것은 돈의 흐름을 만드는 것이다. 어쩌면 이 예매 시스템에서 가장 중요한 부분이라고 할 수 있겠다.

  2. 먼저 돈이 부족하면 continue; 시켜서 메뉴로 보내야 된다. 이 조건을 만들기 위해서는 돈인 money와 비교하기 위한 티켓가격, 여기서는 t_price로 표현하겠다.
    money-t_price < 0 이 조건식을 만족하면 돈이 부족하다는 이야기고 continue; 리턴시키자. 마찬가지로 case 1에서 작성하자.

...변수부분 나머지 생략...
int money = 100000;
int t_price = 5000;

	case 1 : 
    	if(money-t_price<0)
        	JOptionPane.showMessageDialog(null, "잔액이 부족합니다.");
        	continue;
    	choice = Integer.parseInt(JO...
이렇게 만들면 계산되기 전에 continue로 메뉴로 돌려보낼 수 있겠다.
  1. 다음은 티켓이 구매될 때 money에서 티켓가격만큼 감소누적이 되어야 됨으로 t_check라는 불리언타입의 변수를 만들어보자
    이 t_check이 true로 시작해서 구매할 수 없는 조건을 만나면 false로 값을 덮어씌우고 참일 때 계산이 되게 만들면 되겠다.
...변수부분 나머지 생략...
boolean t_chceck;
..생략
while(true) {	
		t_check = true; //case 2에서도 사용할 것이라 여기에 작성함
		choice = Integer.parse......
	case 1 : 
    ...생략
    	age = Integer.pars...
    ...생략
        	if(age > 19) {
		JOptionPane.showMe.....					
		}else {
		t_check = false; //여기서는 계산이 안됨,
		JOptionPane.showMessageDialog(null, "다시 시도해 주세요");					
		}
        
 if(t_chceck) money -= t_price;
 JOptionPane.showMessageDialog(null,"현재잔액: "+money+"원"				
	}
break;
}
  1. 계산이 되는 것을 화인 할 수 있으나 포인트가 적립되지 않는다.
    포인트가 쌓일때 저장되는 공간을 만들어야 되지 point를 정수타입으로 선언하고 point는 예매 할때마다 50%씩 적립시켜주자.
...변수부분 나머지 생략...
int point = 0;
...생략
	 if(t_chceck) {
     		money -= t_price;
            point +=(int)(m_price * 0.5);
            }
 	JOptionPane.showMessageDia.......
point는 누적함수를 사용하여 예매할 때마다 쌓이게 만들었다. 
  1. point를 한번 조회해보자. point에 값이 담겨있으니 간편이 메시지로 출력하면 되겠다.
case 3 : 
JOptionPane.showMessageDialog(null, "현재 잔여 포인트는 "+point+"점 "+"입니다.");
break;

13.포인트를 사용하게 만들 껀데 포인트를 50%나 적립시켜주지 포인트가 있을 때마다 포인트를 자동 사용하게 만들 것이다.
이때 포인트가 있을 때 뿐 아니라 포인트가 티켓보다 많이 있을때 포인트에 티켓만큼 감소시키고 포인트가 적을때는 티켓에서 포인트 만큼 빼고 이 뺀 값을 money에서 차감해야 한다. 그리고 포인트를 다시 0으로 초기화한다.

if(t_check) {
	if(point > 0) {
		if(point - t_price >= 0) {							
		point -= t_price; //포인트가 많다면 포인트 먼저 결재 될것이다.
        	}else {
		money -= (t_price - point);
		point = 0;
		}
	}else {
	money -= t_price;
	point +=(int)(t_price * 0.5);					
	}
	JOpt...ialog(null,"현재잔액: "+money+"원");					
}
위의 코드는 아래와 같이 움직인다. 
1) t_check가 true일때 point가 0보다 큰 값인지 검사
2) point가 0보다 작으면 money에서 티켓만큼 감소누적, 포인트 적립
3) point가 0보다 크면 point가 티켓보다 많은지 검사
4) 포인트가 티켓보다 없으면 티켓가격에서 포인트만큼 빼고 뺀 값을 money에서 감소 누적. point를 0으로 초기화
5) 포인트가 티켓보다 많으면 point에서 티켓가격만큼 감소. 끝.
6) 메시지를 출력한다. 
  1. case 2도 case 1과 동일하게 작성하면 된다. 물론 영화종류를 보여주는 것이 아니라 스넥의 종류를 보여주면 된다.
    지금까지 작성된 코드는 다음과 같다.
package cgv;

import javax.swing.JOptionPane;

public class CGV {
	public static void main(String[] args) {
		String helloMsg  = "어서오세요 CGV입니다.\n";
		String menuMsg = "①예매하기\n②구매하기\n③포인트조회\n④나가기\n";
		String films = "①라이언킹(0800)\n②스파이더맨(1200)\n③사일런스(2300)[청소년 관람 불가]\n④뒤로가기\n";
		String ageMsg = "[청소년 구매 불가 상품]\n나이를 입력하세요\n";
		String buyMenu = "①팝콘\n②콜라\n③맥주\n④뒤로 가기\n";
		int choice = 0;
		int choice2 = 0;
		int age = 0;
		int money = 10_000_000;
		int point = 15000;
		int t_price = 10000;
		int m_price = 5000;
		boolean t_check;
		
		
		
	while(true) {	
		t_check = true;
		choice = Integer.parseInt(JOptionPane.showInputDialog(helloMsg+menuMsg));
		if(choice == 4) break;
		//잘못입력했을때 continue
		if(!(choice >= 1 && choice <= 3)) continue;
		switch(choice) {
		//예매하기 영역
		case 1 : 
			//먼저 빼고 음수인지 확인!!!!
			if(money - t_price < 0) {
				JOptionPane.showMessageDialog(null, "잔액이 부족합니다.");
				continue;
			}
			
			//변수의 재사용 : 위에서 사용하고 더이상 사용하지 않으면 사용 가능
			choice = Integer.parseInt(JOptionPane.showInputDialog(films));
			if(choice == 1) {
				JOptionPane.showMessageDialog(null, "라이언킹 예매 완료(0800)");
			}else if(choice == 2) {
				JOptionPane.showMessageDialog(null, "스파이더맨 예매 완료(1200)");	
			}else if(choice == 3) {
				age = Integer.parseInt(JOptionPane.showInputDialog(ageMsg));
				if(age > 19) {
					JOptionPane.showMessageDialog(null, "사일런스 예매 완료(2300)");					
				}else {
					t_check = false;
					JOptionPane.showMessageDialog(null, "다시 시도해 주세요");					
				}
				
			}else {
				JOptionPane.showMessageDialog(null, "메인 메뉴로 이동합니다.");
				continue;
			}
			if(t_check) {
				if(point > 0) {
					if(point - t_price >= 0) {							
						point -= t_price; //포인트가 많다면 포인트 먼저 결재 될것이다.
					}else {
						money -= (t_price - point);
						point = 0;
					}
				}else {
					money -= t_price;
					point +=(int)(t_price * 0.5);					
				}
				JOptionPane.showMessageDialog(null,"현재잔액: "+money+"원");					
			}
			break;
		//구매하기 영역
		case 2 : 
			if(money - m_price < 0) {
				JOptionPane.showMessageDialog(null, "잔액이 부족합니다.");
				continue;
			}
			
			//변수의 재사용 : 위에서 사용하고 더이상 사용하지 않으면 사용 가능
			choice2 = Integer.parseInt(JOptionPane.showInputDialog(buyMenu));
			if(choice2 == 1) {
				
				JOptionPane.showMessageDialog(null, "팝콘 구매완료");
			}else if(choice2 == 2) {
				JOptionPane.showMessageDialog(null, "콜라 구매완료");
				
			}else if(choice2 == 3) {
				age = Integer.parseInt(JOptionPane.showInputDialog(ageMsg));
				if(age > 19) {
					JOptionPane.showMessageDialog(null, "맥주 구매완료");					
				}else {
					t_check = false;
					JOptionPane.showMessageDialog(null, "다시 시도해 주세요");					
				}
				
			}else {
				JOptionPane.showMessageDialog(null, "메인 메뉴로 이동합니다.");
				continue;
			}
			if(t_check) {
				if(point > 0) {
					if(point - m_price >= 0) {						
						point -= m_price;
					}else {
						money -= (m_price - point);
						point = 0;
					}
				}else {
					money -= m_price;
					point +=(int)(m_price * 0.5);					
				}
				JOptionPane.showMessageDialog(null,"현재잔액: "+money+"원");					
			}
			break;
		//포인트조회 영역
		case 3 : 
			JOptionPane.showMessageDialog(null, "현재 잔여 포인트는 "+point+"점 "+"입니다.");
			break;
		}
		
		}
	}
}

위에 작성된 코드의 한계

앞서 설명한 것과 동일하게 영화와 스넥을 받아오고 지갑과 포인트까지 외부 변수로 받아와야 하지만 여기서는 직접 변수를 초기화하였다는 것에 한계가 있다. 또한 view단이라고 해보았자 사용자가 아닌 개발자 중심이라는 것을 알 수 있다.
결재되는 코드도 보안성에 취약하다는 단점도 존재한다.
위 코드에서는 JAVA 입문자로써 switch와 while, if문 사용 그리고 앞으로 유용하게 사용할 플래그까지 사용해 보았다는 것에 의의를 두어야겠다.
메서드와 클래스를 배우면 두 기능을 이용하여 위 코드를 수정해 보겠다.

좋은 웹페이지 즐겨찾기