diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..3551ef14 --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +.gradle +.idea +build +gradle +out diff --git a/build.gradle b/build.gradle new file mode 100644 index 00000000..3cae2d72 --- /dev/null +++ b/build.gradle @@ -0,0 +1,19 @@ +plugins { + id 'java' +} + +group 'org.example' +version '1.0-SNAPSHOT' + +repositories { + mavenCentral() +} + +dependencies { + testImplementation 'org.junit.jupiter:junit-jupiter-api:5.8.1' + testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.8.1' +} + +test { + useJUnitPlatform() +} \ No newline at end of file diff --git a/docs/feature_list.md b/docs/feature_list.md new file mode 100644 index 00000000..46ad480e --- /dev/null +++ b/docs/feature_list.md @@ -0,0 +1,41 @@ +# 기능 목록 + + +## 콘솔, 파일을 통해 고객 등급(group) 분류 기준 CRU +1. [ ] 콘솔 및 파일을 통해 분류 기준 입력 받음 +2. [X] 분류 기준 설정 +3. [X] 분류 기준 조회 +3. [X] 분류 기준 수정 + + +## 고객 등급 분류 기능 +(정렬 시 오름차순 또는 내림차순 선택 기능 추가) +1.[X] 분류기준에 따른 고객 분류 +2.[X] 분류기준으로 분류된 고객 정보 출력 +3.[X] 분류기준으로 분류된 고객 정보를 이름순(name) 정렬 +4.[X] 분류기준으로 분류된 고객 정보를 총 이용시간(hours) 순으로 정렬 +5. [X] 분류기준으로 분류된 고객 정보를 총 결제금액(totalAmount) 순으로 정렬 + +## 콘솔, 파일을 통해 고객 정보 CRUD +1. [ ] 고객 정보 입력 기능 +2. [x] 고객 정보 추가 +2. [X] 고객 정보 수정 +3. [X] 고객 정보 조회 +4. [X] 고객 정보 삭제 + + +## 예외처리 +1. [ ] 고객 분류 기준이 추가될 경우 수정된 분류기준에 따라 고객 재분류 가능해야한다. +2. [X] 고객 정보가 추가될 때, 다음 시나리오에 대한 예외 처리 + - 배열의 크기가 부족할 수 있음 + - 배열 크기 더블링 (x2, x1.xx) + - 기존 배열의 크기가 5 일 경우, 6번째 고객이 들어온다고 가정. + - 배열의 크기를 더블링 시키고 (10) + - 기존 배열의 데이터를 복붙하고 + - 6번째 고객의 정보도 저장한다. +3. [ ] 고객 정보가 추가될 때, 다음 시나리오에 대한 예외 처리 + - 배열 구멍 뚫리면 안됨 + - 0, 1, 2: null, 3, 4 ⇒ 0, 1, 2, 3, 4: null +4. [ ] 배열의 저장범위를 벗어나게 되면 생기는 예외 처리 +5. [ ] 상황에 알맞는 사용자 정의 예외 클래스 만들기 + \ No newline at end of file diff --git a/gradlew b/gradlew new file mode 100644 index 00000000..1b6c7873 --- /dev/null +++ b/gradlew @@ -0,0 +1,234 @@ +#!/bin/sh + +# +# Copyright © 2015-2021 the original authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +############################################################################## +# +# Gradle start up script for POSIX generated by Gradle. +# +# Important for running: +# +# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is +# noncompliant, but you have some other compliant shell such as ksh or +# bash, then to run this script, type that shell name before the whole +# command line, like: +# +# ksh Gradle +# +# Busybox and similar reduced shells will NOT work, because this script +# requires all of these POSIX shell features: +# * functions; +# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», +# «${var#prefix}», «${var%suffix}», and «$( cmd )»; +# * compound commands having a testable exit status, especially «case»; +# * various built-in commands including «command», «set», and «ulimit». +# +# Important for patching: +# +# (2) This script targets any POSIX shell, so it avoids extensions provided +# by Bash, Ksh, etc; in particular arrays are avoided. +# +# The "traditional" practice of packing multiple parameters into a +# space-separated string is a well documented source of bugs and security +# problems, so this is (mostly) avoided, by progressively accumulating +# options in "$@", and eventually passing that to Java. +# +# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, +# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; +# see the in-line comments for details. +# +# There are tweaks for specific operating systems such as AIX, CygWin, +# Darwin, MinGW, and NonStop. +# +# (3) This script is generated from the Groovy template +# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# within the Gradle project. +# +# You can find Gradle at https://github.com/gradle/gradle/. +# +############################################################################## + +# Attempt to set APP_HOME + +# Resolve links: $0 may be a link +app_path=$0 + +# Need this for daisy-chained symlinks. +while + APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path + [ -h "$app_path" ] +do + ls=$( ls -ld "$app_path" ) + link=${ls#*' -> '} + case $link in #( + /*) app_path=$link ;; #( + *) app_path=$APP_HOME$link ;; + esac +done + +APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit + +APP_NAME="Gradle" +APP_BASE_NAME=${0##*/} + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD=maximum + +warn () { + echo "$*" +} >&2 + +die () { + echo + echo "$*" + echo + exit 1 +} >&2 + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "$( uname )" in #( + CYGWIN* ) cygwin=true ;; #( + Darwin* ) darwin=true ;; #( + MSYS* | MINGW* ) msys=true ;; #( + NONSTOP* ) nonstop=true ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD=$JAVA_HOME/jre/sh/java + else + JAVACMD=$JAVA_HOME/bin/java + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD=java + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then + case $MAX_FD in #( + max*) + MAX_FD=$( ulimit -H -n ) || + warn "Could not query maximum file descriptor limit" + esac + case $MAX_FD in #( + '' | soft) :;; #( + *) + ulimit -n "$MAX_FD" || + warn "Could not set maximum file descriptor limit to $MAX_FD" + esac +fi + +# Collect all arguments for the java command, stacking in reverse order: +# * args from the command line +# * the main class name +# * -classpath +# * -D...appname settings +# * --module-path (only if needed) +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. + +# For Cygwin or MSYS, switch paths to Windows format before running java +if "$cygwin" || "$msys" ; then + APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) + CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) + + JAVACMD=$( cygpath --unix "$JAVACMD" ) + + # Now convert the arguments - kludge to limit ourselves to /bin/sh + for arg do + if + case $arg in #( + -*) false ;; # don't mess with options #( + /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath + [ -e "$t" ] ;; #( + *) false ;; + esac + then + arg=$( cygpath --path --ignore --mixed "$arg" ) + fi + # Roll the args list around exactly as many times as the number of + # args, so each arg winds up back in the position where it started, but + # possibly modified. + # + # NB: a `for` loop captures its iteration list before it begins, so + # changing the positional parameters here affects neither the number of + # iterations, nor the values presented in `arg`. + shift # remove old arg + set -- "$@" "$arg" # push replacement arg + done +fi + +# Collect all arguments for the java command; +# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of +# shell script including quotes and variable substitutions, so put them in +# double quotes to make sure that they get re-expanded; and +# * put everything else in single quotes, so that it's not re-expanded. + +set -- \ + "-Dorg.gradle.appname=$APP_BASE_NAME" \ + -classpath "$CLASSPATH" \ + org.gradle.wrapper.GradleWrapperMain \ + "$@" + +# Use "xargs" to parse quoted args. +# +# With -n1 it outputs one arg per line, with the quotes and backslashes removed. +# +# In Bash we could simply go: +# +# readarray ARGS < <( xargs -n1 <<<"$var" ) && +# set -- "${ARGS[@]}" "$@" +# +# but POSIX shell has neither arrays nor command substitution, so instead we +# post-process each arg (as a line of input to sed) to backslash-escape any +# character that might be a shell metacharacter, then use eval to reverse +# that process (while maintaining the separation between arguments), and wrap +# the whole thing up as a single "set" statement. +# +# This will of course break if any of these variables contains a newline or +# an unmatched quote. +# + +eval "set -- $( + printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | + xargs -n1 | + sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | + tr '\n' ' ' + )" '"$@"' + +exec "$JAVACMD" "$@" diff --git a/gradlew.bat b/gradlew.bat new file mode 100644 index 00000000..107acd32 --- /dev/null +++ b/gradlew.bat @@ -0,0 +1,89 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto execute + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto execute + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/settings.gradle b/settings.gradle new file mode 100644 index 00000000..92426426 --- /dev/null +++ b/settings.gradle @@ -0,0 +1,2 @@ +rootProject.name = 'KDTBE5_Java_ToyProject' + diff --git a/src/main/java/me/smartstore/Main.java b/src/main/java/me/smartstore/Main.java new file mode 100644 index 00000000..9c20405d --- /dev/null +++ b/src/main/java/me/smartstore/Main.java @@ -0,0 +1,10 @@ +package me.smartstore; + +import me.smartstore.runner.MainRunner; + +public class Main { + public static void main(String[] args) { + MainRunner mainRunner = MainRunner.getInstance(); + mainRunner.run(); + } +} diff --git a/src/main/java/me/smartstore/collections/MyArrayList.java b/src/main/java/me/smartstore/collections/MyArrayList.java new file mode 100644 index 00000000..028cf892 --- /dev/null +++ b/src/main/java/me/smartstore/collections/MyArrayList.java @@ -0,0 +1,138 @@ +package me.smartstore.collections; + +import me.smartstore.menu.OrderType; + +import java.util.Arrays; +import java.util.Collections; +import java.util.Iterator; +import java.util.Spliterator; +import java.util.function.Consumer; + +public class MyArrayList implements MyList { + private int size; + private static final int DEFAULT_CAPACITY = 50; + private T[] elements; + + public MyArrayList() { + this.size = 0; + this.elements = (T[]) new Object[DEFAULT_CAPACITY]; + } + + @Override + public void add(T t) { + if (size == elements.length) { + elements = Arrays.copyOf(elements, size * 2); + } + this.elements[size++] = t; + } + + //@Todo: 테스트해야됨 + @Override + public void add(int index, T t) { + if (size == elements.length) { + elements = Arrays.copyOf(elements, size * 2); + } + System.arraycopy(elements, index, elements, index + 1, size - index); + elements[index] = t; + size++; + } + + @Override + public void clear() { + elements = (T[]) new Object[DEFAULT_CAPACITY]; + size = 0; + + } + + @Override + public boolean contains(T t) { + for (T element : elements) { + if (element.equals(t)) { + return true; + } + } + return false; + } + + @Override + public boolean isEmpty() { + return size == 0; + } + + @Override + public boolean remove(T t) { + for (int i = 0; i < size; i++) { + if (elements[i].equals(t)) { + for (int j = i; j < size - 1; j++) { + elements[j] = elements[j + 1]; + } + size--; + return true; + } + } + return false; + } + + public boolean remove(int index) { + if (index < 0 || index > size - 1) { + return false; + } + for (int i = index; i < size - 1; i++) { + elements[i] = elements[i + 1]; + } + size--; + return true; + } + + @Override + public int size() { + return size; + } + + @Override + public void set(int index, T t) { + + } + + @Override + public int indexOf(T t) { + for (int i = 0; i < size; i++) { + if (elements[i].equals(t)) { + return i; + } + } + return -1; + } + + @Override + public T get(int index) { + if (index < 0 || index >= size) { + throw new IndexOutOfBoundsException(); + } + return elements[index]; + } + + public void sort(OrderType orderType) { + if (orderType == OrderType.DESCENDING) { + Arrays.sort(elements, Collections.reverseOrder()); + return; + } + Arrays.sort(elements); + } + + //@Todo Iterator, forEach, Spliterator구현해야됨;; + @Override + public Iterator iterator() { + return null; + } + + @Override + public void forEach(Consumer action) { + MyList.super.forEach(action); + } + + @Override + public Spliterator spliterator() { + return MyList.super.spliterator(); + } +} diff --git a/src/main/java/me/smartstore/collections/MyCollection.java b/src/main/java/me/smartstore/collections/MyCollection.java new file mode 100644 index 00000000..5038cc32 --- /dev/null +++ b/src/main/java/me/smartstore/collections/MyCollection.java @@ -0,0 +1,15 @@ +package me.smartstore.collections; + +public interface MyCollection extends Iterable { + void add(T t); + + void clear(); + + boolean contains(T t); + + boolean isEmpty(); + + boolean remove(T t); + + int size(); +} diff --git a/src/main/java/me/smartstore/collections/MyList.java b/src/main/java/me/smartstore/collections/MyList.java new file mode 100644 index 00000000..ddfc40f7 --- /dev/null +++ b/src/main/java/me/smartstore/collections/MyList.java @@ -0,0 +1,11 @@ +package me.smartstore.collections; + +public interface MyList extends MyCollection { + void add(int index, T t); + void set(int index, T t); + + int indexOf(T t); + + boolean remove(int index); + T get(int index); +} diff --git a/src/main/java/me/smartstore/customer/ClassifiedCustomers.java b/src/main/java/me/smartstore/customer/ClassifiedCustomers.java new file mode 100644 index 00000000..02002bd6 --- /dev/null +++ b/src/main/java/me/smartstore/customer/ClassifiedCustomers.java @@ -0,0 +1,71 @@ +package me.smartstore.customer; + +import me.smartstore.collections.MyArrayList; +import me.smartstore.group.GroupType; + +public class ClassifiedCustomers { + private MyArrayList classifiedByGeneral; + private MyArrayList classifiedByVIP; + private MyArrayList classifiedByVVIP; + private MyArrayList> classifications; + private static ClassifiedCustomers classifiedCustomers; + private SortBy sortBy; + + private ClassifiedCustomers() { + } + + public static ClassifiedCustomers getInstance() { + if (classifiedCustomers == null) { + classifiedCustomers = new ClassifiedCustomers(); + } + return classifiedCustomers; + } + + public void refresh() { + Customers customers = Customers.getInstance(); + MyArrayList customerList = customers.getCustomers(); + initCustomerList(); + + for (Customer customer : customerList) { + if (customer.getGroup() == GroupType.GENERAL) { + classifiedByGeneral.add(customer); + continue; + } + if (customer.getGroup() == GroupType.VIP) { + classifiedByVIP.add(customer); + continue; + } + classifiedByVVIP.add(customer); + } + } + + private void initCustomerList() { + classifiedByGeneral = new MyArrayList<>(); + classifiedByVIP = new MyArrayList<>(); + classifiedByVVIP = new MyArrayList<>(); + } + + public MyArrayList getClassifiedByGeneral() { + return classifiedByGeneral; + } + + public MyArrayList getClassifiedByVIP() { + return classifiedByVIP; + } + + public MyArrayList getClassifiedByVVIP() { + return classifiedByVVIP; + } + + public MyArrayList> getClassifications() { + return classifications; + } + + public SortBy getSortBy() { + return sortBy; + } + + public void setSortBy(SortBy sortBy) { + this.sortBy = sortBy; + } +} diff --git a/src/main/java/me/smartstore/customer/Customer.java b/src/main/java/me/smartstore/customer/Customer.java new file mode 100644 index 00000000..4e706718 --- /dev/null +++ b/src/main/java/me/smartstore/customer/Customer.java @@ -0,0 +1,124 @@ +package me.smartstore.customer; + +import me.smartstore.collections.MyArrayList; +import me.smartstore.group.Group; +import me.smartstore.group.GroupType; +import me.smartstore.group.Groups; + +import java.util.Objects; + +public class Customer implements Comparable { + private String name; + private String id; + private int hours; + private int totalAmount; + private GroupType group; + private ClassifiedCustomers classifiedCustomers; + + public Customer(String name, String id, int hours, int totalAmount) { + this.name = name; + this.id = id; + this.hours = hours; + this.totalAmount = totalAmount; + this.group = judgeCustomerGroup(hours, totalAmount); + this.classifiedCustomers = ClassifiedCustomers.getInstance(); + } + + private GroupType judgeCustomerGroup(int hours, int totalAmount) { + //정렬된 groups요소를 돌며 그 요소의 기준 미만이라면 그 grouptype으로 설정 + Groups groups = Groups.getInstance(); + MyArrayList groupList = groups.getGroups(); + for (int i = 0; i < groupList.size() - 1; i++) { + int currentMinimumHours = groupList.get(i).getParameter().getMinimumHours(); + int currentMinimumTotalAmount = groupList.get(i).getParameter().getMinimumTotalAmount(); + int nextMinimumHours = groupList.get(i + 1).getParameter().getMinimumHours(); + int nextMinimumTotalAmount = groupList.get(i + 1).getParameter().getMinimumTotalAmount(); + + //어떤 기준도 충족 못시킬 때 + if (hours <= currentMinimumHours || totalAmount <= currentMinimumTotalAmount) { + return GroupType.getGroupType(i); + } + //현재 기준 충족 + 다음 기준 미충족 시 현재 기준에 해당하는 등급 부여 + if (hours <= nextMinimumHours && totalAmount <= nextMinimumTotalAmount) { + return groupList.get(i).getCustomerGroup(); + } + } + return GroupType.getGroupType(groupList.size() - 1); + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public int getHours() { + return hours; + } + + public void setHours(int hours) { + this.hours = hours; + } + + public int getTotalAmount() { + return totalAmount; + } + + public void setTotalAmount(int totalAmount) { + this.totalAmount = totalAmount; + } + + public GroupType getGroup() { + return group; + } + + public void setGroup(GroupType group) { + this.group = group; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + Customer customer = (Customer) o; + return hours == customer.hours && totalAmount == customer.totalAmount && Objects.equals(name, customer.name) && Objects.equals(id, customer.id) && group == customer.group; + } + + @Override + public int hashCode() { + return Objects.hash(name, id, hours, totalAmount, group); + } + + @Override + public String toString() { + return "Customer{" + + "name='" + name + '\'' + + ", id='" + id + '\'' + + ", hours=" + hours + + ", totalAmount=" + totalAmount + + ", group=" + group + + '}'; + } + + + @Override + public int compareTo(Customer o) { + if (classifiedCustomers.getSortBy() == SortBy.NAME) { + return this.name.compareTo(o.name); + } + if (classifiedCustomers.getSortBy() == SortBy.HOURS) { + return this.hours - o.hours; + } + return this.totalAmount - o.totalAmount; + } +} diff --git a/src/main/java/me/smartstore/customer/Customers.java b/src/main/java/me/smartstore/customer/Customers.java new file mode 100644 index 00000000..7e57babb --- /dev/null +++ b/src/main/java/me/smartstore/customer/Customers.java @@ -0,0 +1,63 @@ +package me.smartstore.customer; + +import me.smartstore.collections.MyArrayList; +import me.smartstore.group.Group; +import me.smartstore.group.GroupType; +import me.smartstore.group.Groups; + +import java.util.Arrays; + +public class Customers { + private static Customers instance; + private Groups groups; + private final MyArrayList customers = new MyArrayList<>(); + + private Customers() { + groups = Groups.getInstance(); + } + + public static Customers getInstance() { + if (instance == null) { + instance = new Customers(); + } + return instance; + } + + public void refreshCustomersGroup() { + MyArrayList groupList = groups.getGroups(); + + for (int i = 0; i < customers.size(); i++) { + Customer currentCustomer = customers.get(i); + int hours = currentCustomer.getHours(); + int totalAmount = currentCustomer.getTotalAmount(); + + for (int j = 0; j < groupList.size() - 1; j++) { + int currentMinimumHours = groupList.get(j).getParameter().getMinimumHours(); + int currentMinimumTotalAmount = groupList.get(j).getParameter().getMinimumTotalAmount(); + int nextMinimumHours = groupList.get(j + 1).getParameter().getMinimumHours(); + int nextMinimumTotalAmount = groupList.get(j + 1).getParameter().getMinimumTotalAmount(); + //어떤 기준도 충족 못시킬 때 + if (hours <= currentMinimumHours || totalAmount <= currentMinimumTotalAmount) { + currentCustomer.setGroup(GroupType.getGroupType(j)); + break; + } + if (hours <= nextMinimumHours && totalAmount <= nextMinimumTotalAmount) { + currentCustomer.setGroup(GroupType.getGroupType(j)); + break; + } + } + currentCustomer.setGroup(GroupType.getGroupType(groupList.size() - 1)); + } + } + + public MyArrayList getCustomers() { + return customers; + } + + @Override + public String toString() { + return "Customers{" + + "customers=" + customers + + '}'; + } +} diff --git a/src/main/java/me/smartstore/customer/SortBy.java b/src/main/java/me/smartstore/customer/SortBy.java new file mode 100644 index 00000000..ddba7e13 --- /dev/null +++ b/src/main/java/me/smartstore/customer/SortBy.java @@ -0,0 +1,10 @@ +package me.smartstore.customer; + +public enum SortBy { + NAME, + HOURS, + TOTAL_AMOUNT; + + + +} diff --git a/src/main/java/me/smartstore/group/Group.java b/src/main/java/me/smartstore/group/Group.java new file mode 100644 index 00000000..ea7effcb --- /dev/null +++ b/src/main/java/me/smartstore/group/Group.java @@ -0,0 +1,19 @@ +package me.smartstore.group; + +public class Group { + private GroupType customerGroup; + private Parameter parameter; + + public Group(GroupType customerGroup, Parameter parameter) { + this.customerGroup = customerGroup; + this.parameter = parameter; + } + + public GroupType getCustomerGroup() { + return customerGroup; + } + + public Parameter getParameter() { + return parameter; + } +} diff --git a/src/main/java/me/smartstore/group/GroupType.java b/src/main/java/me/smartstore/group/GroupType.java new file mode 100644 index 00000000..3b6db59a --- /dev/null +++ b/src/main/java/me/smartstore/group/GroupType.java @@ -0,0 +1,13 @@ +package me.smartstore.group; + +public enum GroupType { + GENERAL, + VIP, + VVIP; + + private static final GroupType[] groupTypes = GroupType.values(); + + public static GroupType getGroupType(int i) { + return groupTypes[i]; + } +} \ No newline at end of file diff --git a/src/main/java/me/smartstore/group/Groups.java b/src/main/java/me/smartstore/group/Groups.java new file mode 100644 index 00000000..65f3ed24 --- /dev/null +++ b/src/main/java/me/smartstore/group/Groups.java @@ -0,0 +1,32 @@ +package me.smartstore.group; + +import me.smartstore.collections.MyArrayList; + +public class Groups { + private MyArrayList groups = new MyArrayList<>(); + private static Groups instance; + + private Groups() { + groups.add(new Group(GroupType.GENERAL, new Parameter())); + groups.add(new Group(GroupType.VIP, new Parameter())); + groups.add(new Group(GroupType.VVIP, new Parameter())); + } + + public static Groups getInstance() { + if (instance == null) { + instance = new Groups(); + } + return instance; + } + + public MyArrayList getGroups() { + return groups; + } + + @Override + public String toString() { + return "Groups{" + + "groups=" + groups + + '}'; + } +} diff --git a/src/main/java/me/smartstore/group/Parameter.java b/src/main/java/me/smartstore/group/Parameter.java new file mode 100644 index 00000000..bef13bd5 --- /dev/null +++ b/src/main/java/me/smartstore/group/Parameter.java @@ -0,0 +1,36 @@ +package me.smartstore.group; + +public class Parameter { + private int minimumHours; + private int minimumTotalAmount; + + public Parameter(){} + public Parameter(int minimumHours, int minimumTotalAmount) { + this.minimumHours = minimumHours; + this.minimumTotalAmount = minimumTotalAmount; + } + + public int getMinimumHours() { + return minimumHours; + } + + public void setMinimumHours(int minimumHours) { + this.minimumHours = minimumHours; + } + + public int getMinimumTotalAmount() { + return minimumTotalAmount; + } + + public void setMinimumTotalAmount(int minimumTotalAmount) { + this.minimumTotalAmount = minimumTotalAmount; + } + + @Override + public String toString() { + return "Parameter{" + + "minimumHours=" + minimumHours + + ", minimumTotalAmount=" + minimumTotalAmount + + '}'; + } +} diff --git a/src/main/java/me/smartstore/menu/CustomerMenu.java b/src/main/java/me/smartstore/menu/CustomerMenu.java new file mode 100644 index 00000000..26b5fc0c --- /dev/null +++ b/src/main/java/me/smartstore/menu/CustomerMenu.java @@ -0,0 +1,176 @@ +package me.smartstore.menu; + +import me.smartstore.collections.MyArrayList; +import me.smartstore.customer.Customer; + +import java.io.IOException; + +public class CustomerMenu extends Menu implements DataCRUD { + private static CustomerMenu customerMenu; + + private CustomerMenu() { + } + + public static CustomerMenu getInstance() { + if (customerMenu == null) { + customerMenu = new CustomerMenu(); + } + return customerMenu; + } + + public void run() { + int customerMenuNumber = 0; + while (customerMenuNumber != 5) { + printCustomerInitMenu(); + customerMenuNumber = readNumber(5); + if (customerMenuNumber == 1) { + addData(); + } else if (customerMenuNumber == 2) { + viewData(); + } else if (customerMenuNumber == 3) { + updateData(); + } else if (customerMenuNumber == 4) { + deleteData(); + } + } + } + + @Override + public void addData() { + try { + Customer customer = inputCustomerData(); + MyArrayList customerList = customers.getCustomers(); + customerList.add(customer); + } catch (IOException e) { + System.out.println(e.getMessage()); + } + } + + //@Todo 예외처리 + private Customer inputCustomerData() throws IOException { + //이름, id, 누적 시간, 누적 결제 금액을 차례로 입력받도록 함. + System.out.println("이름을 입력하세요"); + String name = br.readLine(); + System.out.println("ID를 입력하세요"); + String id = br.readLine(); + System.out.println("누적 이용시간을 입력하세요."); + int hour = Integer.parseInt(br.readLine()); + System.out.println("누적 결제금액을 입력하세요."); + int totalAmount = Integer.parseInt(br.readLine()); + + return new Customer(name, id, hour, totalAmount); + } + + @Override + public void viewData() { + if (validator.isCustomerListEmpty()) { + return; + } + MyArrayList customerList = customers.getCustomers(); + for (int i = 0; i < customerList.size(); i++) { + System.out.println(customerList.get(i)); + } + } + + @Override + public void updateData() { + //변경할 요소의 index를 입력받음 -> 수정 희망하는 정보 받음 + viewData(); + MyArrayList customerList = getCustomers(); + if (customerList == null) { + return; + } + int listSize = customerList.size(); + System.out.print("수정을 희망하는 고객 번호를 입력해주세요"); + System.out.print(listSize >= 2 ? "(1~" + listSize + ")" : ""); + int customerNumber = readNumber(listSize); + + printCustomerUpdateMessage(); + int updateMenuNumber = 0; + try { + updateMenuNumber = Integer.parseInt(br.readLine()); + if (updateMenuNumber == 5) { + return; + } + inputNewData(updateMenuNumber, customerNumber); + } catch (IOException e) { + System.out.println(e.getMessage()); + } + } + + private MyArrayList getCustomers() { + MyArrayList customerList = customers.getCustomers(); + if (customerList.isEmpty()) { + System.out.println("등록된 고객정보가 존재하지 않습니다."); + //예외발생 vs null리턴? + return null; + } + return customerList; + } + + private void printCustomerUpdateMessage() { + System.out.println("=============================="); + System.out.println("수정할 정보를 선택해주세요"); + System.out.println("1. 이름"); + System.out.println("2. ID"); + System.out.println("3. 누적 이용 시간"); + System.out.println("4. 누적 결제 금액"); + System.out.println("5. 수정 취소"); + System.out.println("=============================="); + System.out.print("수정할 정보를 선택해주세요(1~5): "); + } + + private void inputNewData(int updateMenuNumber, int customerNumber) throws IOException { + MyArrayList customerList = customers.getCustomers(); + Customer customer = customerList.get(customerNumber - 1); + + if (updateMenuNumber == 1) { + System.out.println("새로운 이름을 입력해주세요."); + String name = br.readLine(); + customer.setName(name); + return; + } + if (updateMenuNumber == 2) { + System.out.println("새로운 ID를 입력해주세요."); + String id = br.readLine(); + customer.setId(id); + return; + } + if (updateMenuNumber == 3) { + System.out.println("새로운 누적 이용 시간을 입력해주세요."); + int hours = Integer.parseInt(br.readLine()); + customer.setHours(hours); + return; + } + System.out.println("새로운 누적 결제 금액을 입력해주세요."); + int totalAmount = Integer.parseInt(br.readLine()); + customer.setTotalAmount(totalAmount); + } + + @Override + public void deleteData() { + viewData(); + MyArrayList customerList = customers.getCustomers(); + int listSize = customerList.size(); + if (listSize < 1) { + System.out.println("고객이 존재하지 않습니다."); + return; + } + //@Todo 뒤로가기 추가 + System.out.print("삭제할 고객 번호를 입력해주세요"); + System.out.print(listSize >= 2 ? "(1~" + listSize + ")" : ""); + int customerNumber = readNumber(listSize); + customerList.remove(customerNumber); + } + + public void printCustomerInitMenu() { + 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("=============================="); + System.out.print("메뉴번호를 입력해주세요: "); + } +} diff --git a/src/main/java/me/smartstore/menu/DataCRUD.java b/src/main/java/me/smartstore/menu/DataCRUD.java new file mode 100644 index 00000000..6d647cc5 --- /dev/null +++ b/src/main/java/me/smartstore/menu/DataCRUD.java @@ -0,0 +1,12 @@ +package me.smartstore.menu; + +public interface DataCRUD { + + void addData(); + + void viewData(); + + void updateData(); + + void deleteData(); +} diff --git a/src/main/java/me/smartstore/menu/GroupMenu.java b/src/main/java/me/smartstore/menu/GroupMenu.java new file mode 100644 index 00000000..e6269d17 --- /dev/null +++ b/src/main/java/me/smartstore/menu/GroupMenu.java @@ -0,0 +1,162 @@ +package me.smartstore.menu; + +import me.smartstore.collections.MyArrayList; +import me.smartstore.group.Group; +import me.smartstore.group.GroupType; +import me.smartstore.group.Parameter; + +import java.io.IOException; +import java.util.NoSuchElementException; + +public class GroupMenu extends Menu implements DataCRUD { + private static GroupMenu groupMenu; + + private GroupMenu() { + } + + public static GroupMenu getInstance() { + if (groupMenu == null) { + groupMenu = new GroupMenu(); + } + return groupMenu; + } + + public void run() { + int groupMenu = 0; + while (groupMenu != 4) { + printGroupInitMenu(); + groupMenu = readNumber(4); + if (groupMenu == 1) { + addData(); + } else if (groupMenu == 2) { + viewData(); + } else if (groupMenu == 3) { + updateData(); + } + } + } + + @Override + public void addData() { + //변경할 등급 선택 + printGroupSelectionMessage(); + int groupNumber = readNumber(3); + //groupNumber to group + GroupType groupType = groupNumberToGroupType(groupNumber); + //groupList에서 입력받은 등급에 해당하는 요소를 찾음 + insert(groupType); + } + + + private void printGroupSelectionMessage() { + System.out.println("다음 등급 중 하나를 선택해주세요."); + System.out.println("1. GENERAL"); + System.out.println("2. VIP"); + System.out.println("3. VVIP"); + System.out.println("=============================="); + System.out.print("번호를 입력해주세요: "); + } + + private GroupType groupNumberToGroupType(int groupNumber) { + if (groupNumber == 1) { + return GroupType.GENERAL; + } + if (groupNumber == 2) { + return GroupType.VIP; + } + return GroupType.VVIP; + } + + private void insert(GroupType groupType) { + Parameter parameter = findParameter(groupType); + //찾은 요소가 이미 입력이 된 경우 return + if (parameter.getMinimumHours() != 0 || parameter.getMinimumTotalAmount() != 0) { + System.out.println("이미 기준이 등록된 등급입니다."); + return; + } + insertInputParameter(parameter); + } + + private void insertInputParameter(Parameter parameter) { + //기준을 입력할 메뉴 입력 1: 누적 시간/ 2: 누적 결제 금액 + printInsertParameterMessage(); + int parameterNumber = readNumber(3); + try { + //누적 시간 입력 받음 + if (parameterNumber == 1) { + System.out.println("누적 이용 시간을 입력해주세요."); + int hours = Integer.parseInt(br.readLine()); + parameter.setMinimumHours(hours); + + } else if (parameterNumber == 2) { + //누적 결제 금액 입력 받음 + System.out.println("누적 결제 금액을 입력해주세요."); + int totalAmount = Integer.parseInt(br.readLine()); + parameter.setMinimumTotalAmount(totalAmount); + } else { + customers.refreshCustomersGroup(); + return; + } + //3이 입력되기 전까지 재귀 호출해서 메뉴 실행 상태 유지 + insertInputParameter(parameter); + } catch (IOException e) { + System.out.println(e.getMessage()); + } + } + + private void printInsertParameterMessage() { + System.out.println("=============================="); + System.out.println("다음 중 입력할 기준을 선택해주세요."); + System.out.println("1. 누적 이용 시간"); + System.out.println("2. 누적 결제 금액"); + System.out.println("3. 뒤로 가기"); + System.out.println("=============================="); + } + + private Parameter findParameter(GroupType groupType) { + if (validator.isGroupListEmpty()) { + return null; + } + MyArrayList groupList = groups.getGroups(); + for (int i = 0; i < groupList.size(); i++) { + if (groupList.get(i).getCustomerGroup() == groupType) { + return groupList.get(i).getParameter(); + } + } + throw new NoSuchElementException("해당하는 등급이 존재하지 않습니다."); + } + + @Override + public void viewData() { + printGroupSelectionMessage(); + int groupNumber = readNumber(3); + //groupNumber to group + GroupType groupType = groupNumberToGroupType(groupNumber); + Parameter parameter = findParameter(groupType); + System.out.println(parameter); + } + + @Override + public void updateData() { + printGroupSelectionMessage(); + int groupNumber = readNumber(3); + GroupType groupType = groupNumberToGroupType(groupNumber); + Parameter parameter = findParameter(groupType); + insertInputParameter(parameter); + } + + @Override + public void deleteData() { + + } + + public void printGroupInitMenu() { + System.out.println("=============================="); + System.out.println("1. 고객 등급 기준 추가"); + System.out.println("2. 고객 등급 기준 조회"); + System.out.println("3. 고객 등급 기준 수정"); + System.out.println("4. 뒤로 가기"); + System.out.println("=============================="); + System.out.print("메뉴번호를 입력해주세요: "); + } +} diff --git a/src/main/java/me/smartstore/menu/Menu.java b/src/main/java/me/smartstore/menu/Menu.java new file mode 100644 index 00000000..e5ad5d73 --- /dev/null +++ b/src/main/java/me/smartstore/menu/Menu.java @@ -0,0 +1,67 @@ +package me.smartstore.menu; + +import me.smartstore.customer.Customer; +import me.smartstore.customer.Customers; +import me.smartstore.customer.ClassifiedCustomers; +import me.smartstore.group.Groups; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; + +public class Menu { + private static Menu menu; + protected BufferedReader br; + protected Customers customers; + protected Groups groups; + protected ClassifiedCustomers classifiedCustomers; + protected Validator validator; + + protected Menu() { + br = new BufferedReader(new InputStreamReader(System.in)); + customers = Customers.getInstance(); + groups = Groups.getInstance(); + classifiedCustomers = ClassifiedCustomers.getInstance(); + validator = Validator.getInstance(); + } + + public static Menu getInstance() { + if (menu == null) { + menu = new Menu(); + } + return menu; + } + + public int inputInitMenuNumber() { + printInitMenu(); + return readNumber(4); + } + + private void printInitMenu() { + System.out.println("=============================="); + System.out.println("1. 고객 등급 기준 설정"); + System.out.println("2. 고객 정보"); + System.out.println("3. 등급별 고객 정보 요약"); + System.out.println("4. 프로그램 종료"); + System.out.println("=============================="); + System.out.print("메뉴번호를 입력해주세요: "); + + } + + protected int readNumber(int end) { + int menuNumber = 0; + while (menuNumber == 0) { + try { + int temp = Integer.parseInt(br.readLine()); + if (temp >= 1 && temp <= end) { + menuNumber = temp; + } else { + System.out.printf("1부터 %d까지의 숫자를 입력해주세요.\n", end); + } + } catch (IOException e) { + System.out.println(e.getMessage()); + } + } + return menuNumber; + } +} diff --git a/src/main/java/me/smartstore/menu/OrderType.java b/src/main/java/me/smartstore/menu/OrderType.java new file mode 100644 index 00000000..182f7423 --- /dev/null +++ b/src/main/java/me/smartstore/menu/OrderType.java @@ -0,0 +1,15 @@ +package me.smartstore.menu; + +import me.smartstore.customer.SortBy; + +public enum OrderType { + NONE, + ACSENDING, + DESCENDING; + + private static final OrderType[] orderTypes = OrderType.values(); + + public static OrderType getOrderType(int i) { + return orderTypes[i-1]; + } +} diff --git a/src/main/java/me/smartstore/menu/SummaryMenu.java b/src/main/java/me/smartstore/menu/SummaryMenu.java new file mode 100644 index 00000000..9899e126 --- /dev/null +++ b/src/main/java/me/smartstore/menu/SummaryMenu.java @@ -0,0 +1,112 @@ +package me.smartstore.menu; + +import me.smartstore.collections.MyArrayList; +import me.smartstore.customer.Customer; +import me.smartstore.customer.SortBy; +import me.smartstore.group.GroupType; + +import java.io.IOException; + +public class SummaryMenu extends Menu { + private static SummaryMenu summaryMenu; + + private SummaryMenu() { + } + + public static SummaryMenu getInstance() { + if (summaryMenu == null) { + summaryMenu = new SummaryMenu(); + } + return summaryMenu; + } + + public void run() { + if (validator.isCustomerListEmpty()) { + return; + } + classifiedCustomers.refresh(); + int summaryNumber = 0; + while (summaryNumber != 5) { + summaryNumber = readNumber(5); + printSummaryInitMenu(); + if (summaryNumber == 1) { + summary(OrderType.NONE); + } else if (summaryNumber == 2) { + summarySortByName(); + } else if (summaryNumber == 3) { + summarySortByHours(); + } else if (summaryNumber == 4) { + summarySortByTotalAmount(); + } + } + } + + private void summary(OrderType orderType) { + GroupType[] groupTypes = GroupType.values(); + MyArrayList> classifications = classifiedCustomers.getClassifications(); + printCustomerSummary(orderType, groupTypes, classifications); + } + + private void printCustomerSummary(OrderType orderType, GroupType[] groupTypes, MyArrayList> classifications) { + for (int i = 0; i < GroupType.values().length; i++) { + System.out.println("=============================="); + System.out.printf("그룹: %s", groupTypes[i]); + System.out.println("=============================="); + MyArrayList currentClassification = classifications.get(i); + if (orderType != OrderType.NONE) { + currentClassification.sort(orderType); + } + for (int j = 0; j < currentClassification.size(); i++) { + System.out.println(j + ": " + currentClassification.get(j)); + } + } + System.out.println("=============================="); + } + + private void summarySortByName() { + OrderType orderType = inputOrderType(); + //등급 기준에 따라 정렬 + classifiedCustomers.setSortBy(SortBy.NAME); + summary(orderType); + } + + private void summarySortByHours() { + OrderType orderType = inputOrderType(); + classifiedCustomers.setSortBy(SortBy.HOURS); + summary(orderType); + } + + private void summarySortByTotalAmount() { + OrderType orderType = inputOrderType(); + classifiedCustomers.setSortBy(SortBy.TOTAL_AMOUNT); + summary(orderType); + } + + private OrderType inputOrderType() { + //오름차순, 내림차순 입력(OrderType이용) + int ascendingNumber = 0; + while (ascendingNumber == 0) { + try { + int input = Integer.parseInt(br.readLine()); + if (input == 1 || input == 2) { + ascendingNumber = input; + } + System.out.println("1또는 2를 입력해주세요."); + } catch (IOException e) { + System.out.println(e.getMessage()); + } + } + return OrderType.getOrderType(ascendingNumber); + } + + public void printSummaryInitMenu() { + 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("=============================="); + System.out.print("메뉴번호를 입력해주세요: "); + } +} diff --git a/src/main/java/me/smartstore/menu/Validator.java b/src/main/java/me/smartstore/menu/Validator.java new file mode 100644 index 00000000..88bd41a5 --- /dev/null +++ b/src/main/java/me/smartstore/menu/Validator.java @@ -0,0 +1,43 @@ +package me.smartstore.menu; + +import me.smartstore.collections.MyArrayList; +import me.smartstore.customer.Customer; +import me.smartstore.customer.Customers; +import me.smartstore.group.Group; +import me.smartstore.group.Groups; + +public class Validator { + private static Validator validator; + private Customers customers; + private Groups groups; + + private Validator() { + customers = Customers.getInstance(); + groups = Groups.getInstance(); + } + + public static Validator getInstance() { + if (validator == null) { + validator = new Validator(); + } + return validator; + } + + public boolean isCustomerListEmpty() { + MyArrayList customerList = customers.getCustomers(); + if (customerList.isEmpty()) { + System.out.println("등록된 고객 정보가 존재하지 않습니다."); + return true; + } + return false; + } + + public boolean isGroupListEmpty() { + MyArrayList groupList = groups.getGroups(); + if (groupList.isEmpty()) { + System.out.println("등록된 등급 기준이 존재하지 않습니다"); + return true; + } + return false; + } +} diff --git a/src/main/java/me/smartstore/runner/MainRunner.java b/src/main/java/me/smartstore/runner/MainRunner.java new file mode 100644 index 00000000..8894dac8 --- /dev/null +++ b/src/main/java/me/smartstore/runner/MainRunner.java @@ -0,0 +1,44 @@ +package me.smartstore.runner; + +import me.smartstore.menu.CustomerMenu; +import me.smartstore.menu.GroupMenu; +import me.smartstore.menu.Menu; +import me.smartstore.menu.SummaryMenu; + +public class MainRunner { + private static MainRunner mainRunner; + private Menu menu; + private GroupMenu groupMenu; + private CustomerMenu customerMenu; + private SummaryMenu summaryMenu; + + //runner -> GroupMenuRunner, SummaryMenuRunner, CustomerMenuRunner 로 분리 + private MainRunner() { + this.menu = Menu.getInstance(); + this.groupMenu = GroupMenu.getInstance(); + this.summaryMenu = SummaryMenu.getInstance(); + this.customerMenu = CustomerMenu.getInstance(); + } + + public static MainRunner getInstance() { + if (mainRunner == null) { + mainRunner = new MainRunner(); + } + return mainRunner; + } + + public void run() { + int initMenu = 0; + while (initMenu != 4) { + initMenu = menu.inputInitMenuNumber(); + if (initMenu == 1) { + groupMenu.run(); + } else if (initMenu == 2) { + customerMenu.run(); + } else if (initMenu == 3) { + summaryMenu.run(); + } + } + } + +}