메뉴판을 보고 주문할 수 있는 Java 프로그램
터미널에 간단하게 출력
메뉴 클래스와 주문 클래스, 상속 기능을 활용
브랜드 : 스타벅스
메인 메뉴 : 커피, 스무디, 디저트, 빵
상품 메뉴 : 아메리카노 ..(생략).. 샌드위치 등
가장 먼저 클래스 설계, 연관 관계 설계를 해준다. 사실 아직 객체지향을 완전히 자유롭게 다루지 못해서 이 단계가 가장 어려웠다..
↓ 구현 전 다이어그램을 대충 그려보았으나(다시봐도 엉망인듯) 실제 설계는 아래와 다르다.. 후술하겠음
우선 메인 메뉴들을 위한 Menu 클래스와 상품 메뉴들을 위한 Products 클래스 생성 후 Products 클래스가 Menu 클래스를 상속하도록 하였다.
첫 번째, 가장 큰 고민 커피와 같은 메인 메뉴들을 객체로 생성해야 하는지 또 다른 클래스로 생성해야 하는지였다. 둘 다 해 본 결과 결국 메뉴들은 가지고 있는 변수와 메서드의 종류가 같고 다른 클래스로 생성시 관리가 어려워져 Menu 타입 객체로 생성 후, mainMenu ArrayList
를 생성하여 관리하는 것으로 결정.
두 번째, Order와 Cancel이 Menu 타입의 객체가 맞는지, mainMenu 리스트에 넣어야 하는지, 다른 클래스로 생성해야 하는지, 아예 생성할 필요가 없는지.. 에 대한 고민이었다. 결론적으로 Order의 경우 Order 화면에 출력하기 위한 변수와 메서드가 완전히 다르므로 다른 클래스로 생성, Cancel은 하나의 동작만을 수행하므로 그냥 함수로 만들었다.
세 번째, 생성한 상품들을 어떻게 저장할 것인가. 이 프로그램의 구성은 메인 메뉴(ex. coffee) 안에 상품 메뉴(ex. americano)들이 있는 형태이므로 이 형태를 어떻게 객체지향으로 표현해야 하는가에 대한 고민이 하나하나의 고민으로 이어진 것 같다.
상품 선택시 상품 이름으로 선택을 하게 되는데 이름을 통해 객체를 찾기에 용이하기 위해 처음엔 map으로 선언하여 map<상품 이름, 상품 객체>
와 같은 형태로 저장하였다. 그런데 하고 보니 중복 저장인 것 같다는 생각이 들어 ArrayList<상품 객체>
로 변경 후 상품 이름은 getter를 통해 객체에서 뽑아서 사용하는 것으로 변경하였다.
네 번째, main menu 화면 출력을 위한 클래스를 따로 생성해야 하는가? 이것 또한 클래스를 생성해 보았으나 이 경우 다른 클래스에서 메인 메뉴 클래스의 변수와 메서드를 가져다 쓸 일이 많아 불편하였고 결국 main 클래스에서 displayMainMenu()
메서드로 작동하도록 변경하였다.
Class : Main, Menu, Products, Order
Menu Class
public class Menu {
private String name; // 메뉴 이름
private String script; // 메뉴 설명
public ArrayList<Products> menuList = new ArrayList<>(); // 상품 리스트
public Menu(String name, String script){
this.name = name;
this.script = script;
}
public Products displayMenu() {
// 메뉴 선택시 출력 화면
}
}
Products Class
public class Products extends Menu { // Menu 클래스 상속
private int price; // 상품 가격
public Products(String name, String script, int price) {
super(name, script);
this.price = price;
}
}
Order Class
public class Order {
ArrayList<Products> orderList = new ArrayList<>(); // 장바구니 목록
int totalPrice; // 총 주문 금액
int waitingNum = 1; // 대기 번호
private String name = "Order";
private String script = "장바구니를 확인 후 주문합니다.";
public void displayOrder(){
// 장바구니 출력
}
public void addList(Products p){
// 전달받은 상품 객체 장바구니에 추가
}
public void clearOrder(){
// 장바구니 비우기
}
Main
public class Main {
public static ArrayList<Menu> mainMenuList = new ArrayList<>(); // 메인 메뉴 리스트
public static Order order = new Order(); // Order 객체 생성
public static void displayMainMenu(){
// 메인 메뉴 출력
}
public static void main(String[] args) {
// 메인 (메뉴 리스트) 생성
Menu coffeeMenu = new Menu("Coffee", "스타벅스만의 아라비카 커피");
mainMenuList.add(coffeeMenu);
// 커피 (상품 리스트) 생성
coffeeMenu.menuList.add(new Products("Espresso", "에스프레소 설명", 4000));
coffeeMenu.menuList.add(...);
// 메인 메뉴 실행
displayMainMenu();
}
맨 처음 설계가 정확하지 않아 코드로 직접 구현해보면서 여러 문제에 부딪치고 어떤 것이 더 나은 것인지 확신하지 못하고 방향을 이리저리 바꿔가면서 설계를 하였는데, 객체 지향에 익숙해져 처음 틀을 잘 잡을 수 있게 되면 구현 시간이 훨씬 단축될 것 같다.