diff --git a/.gitignore b/.gitignore
new file mode 100644
index 00000000..68c5ea0f
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,9 @@
+### Example user template template
+### Example user template
+
+# IntelliJ project files
+.idea
+*.iml
+out
+gen
+README.md
\ No newline at end of file
diff --git a/README.md b/README.md
deleted file mode 100644
index b0eb52bb..00000000
--- a/README.md
+++ /dev/null
@@ -1,33 +0,0 @@
-
-
-### 자바 토이프로젝트
-> 제출자 - 최은빈
-> 출시일 - 23.04.27.
-> 제출일 - 23.05.10.
-
-- [프로젝트 설명서](https://echoiing-fastcampus.notion.site/Smart-Store-47ea8a0b4b084301bd1eefbabe3426af)를 풀어서 제출하시오. 💻
-
-- 파일 이름 작성법 📂
- - ````me.smartstore```` 패키지 생성
-- 제출방법
- - 본인의 이름으로 ````branch````를 생성하여 ````push````후 ````pull request```` 작성
- - 예시
- - branch 이름 - ````FirstNameLastName````
- - commit 메시지 (멘토 리뷰 이전) - [1차 VER1.0...] Java ToyProject upload by FirstNameLastName (labeling도 가능: ````first````)
- - commit 메시지 (멘토 리뷰 이전) - [1차 VER2.0...] Java ToyProject upload by FirstNameLastName (labeling도 가능: ````second````)
- - commit 메시지 (멘토 리뷰 이후) - [2차] Java ToyProject upload by FirstNameLastName (labeling도 가능: ````resubmit````)
- - PR 메시지는 본인이 하고 싶은 말이나 질문을 적어주세요.
- - ````코드리뷰 빡세게 부탁드립니다.```` ````클린한 코드인지 봐주세요.```` ````이 코드의 조금 더 나은 방법이 있을까요.````
- - ````~~번 문제 풀지 못했습니다.```` ````~~번 문제 풀이 방법을 알려주시면 감사하겠습니다.````
- - ````결과는 나왔는데 맞는지 모르겠습니다.````
-- 리뷰관련 [프로세스 🔖](https://quickest-asterisk-75d.notion.site/a8d233d87f0945cbaa8f71300515587d?p=b658d277f52843dd9e1e8322233c9006&pm=s)
- - ```PEER REVIEW``` - 과제 기간동안 본인 과제 완료 후, 다른 수강생들의 PR을 보며 피어리뷰 가능 (댓글 이용)
- - ```MENTOR REVIEW``` - 과제 기간 이후에 멘토진 코드 리뷰 (댓글 이용)
- - 멘토님이 작성한 댓글 이후에는 수강생이 댓글 자제 (혼선 막기 위함)
-- 주의사항 🔥
- - 본인 ```branch``` -> ```main branch``` PR 상태로 제출부탁드립니다.
- - ```main branch```에 본인 ```branch```의 ```commit```을 ```merge``` 하지 마시기 바랍니다.
- - ```git ignore``` 활용 적극 권장 ‼
- - 문제풀이 코드가 아닌 .idea, out과 같은 파일은 제출 하지 마세요 🥲
-
-
diff --git a/me/smartstore/Main.java b/me/smartstore/Main.java
new file mode 100644
index 00000000..549a8040
--- /dev/null
+++ b/me/smartstore/Main.java
@@ -0,0 +1,8 @@
+package me.smartstore;
+
+public class Main {
+ public static void main(String[] args) {
+ SmartStoreApp.getInstance().test().run(); // function chaining
+ // SmartStoreApp.getInstance().run();
+ }
+}
diff --git a/me/smartstore/SmartStoreApp.java b/me/smartstore/SmartStoreApp.java
new file mode 100644
index 00000000..2473b9bf
--- /dev/null
+++ b/me/smartstore/SmartStoreApp.java
@@ -0,0 +1,64 @@
+package me.smartstore;
+
+import me.smartstore.customer.Customer;
+import me.smartstore.customer.Customers;
+import me.smartstore.group.Group;
+import me.smartstore.group.GroupType;
+import me.smartstore.group.Groups;
+import me.smartstore.group.Parameter;
+import me.smartstore.menu.*;
+
+public class SmartStoreApp {
+ private final Groups allGroups = Groups.getInstance();
+ private final Customers allCustomers = Customers.getInstance();
+
+ private final MainMenu mainMenu = MainMenu.getInstance();
+
+ // singleton
+ private static SmartStoreApp smartStoreApp;
+
+ public static SmartStoreApp getInstance() {
+ if (smartStoreApp == null) {
+ smartStoreApp = new SmartStoreApp();
+ }
+ return smartStoreApp;
+ }
+
+ private SmartStoreApp() {}
+
+ public void details() {
+ System.out.println("\n\n===========================================");
+ System.out.println(" Title : SmartStore Customer Classification");
+ System.out.println(" Release Date : 23.05.10");
+ System.out.println(" Copyright 2023 WooSeok All rights reserved.");
+ System.out.println("===========================================\n");
+ }
+
+ public SmartStoreApp test() {
+ allGroups.add(new Group(new Parameter(10, 100000), GroupType.GENERAL));
+ allGroups.add(new Group(new Parameter(20, 200000), GroupType.VIP));
+ allGroups.add(new Group(new Parameter(30, 300000), GroupType.VVIP));
+
+ for (int i = 0; i < 26; i++) {
+ allCustomers.add(new Customer(
+ Character.toString((char) ('a' + i)),
+ (char) ('a' + i) + "123",
+ ((int) (Math.random() * 5) + 1) * 10,
+ ((int) (Math.random() * 5) + 1) * 100000));
+ }
+
+ System.out.println("allCustomers = " + allCustomers);
+ System.out.println("allGroups = " + allGroups);
+
+ // @TODO: refresh do not implemented yet.
+ allCustomers.refresh();
+
+ return this; // smartStoreApp
+ }
+
+ public void run() {
+ details();
+ mainMenu.manage();
+
+ }
+}
diff --git a/me/smartstore/arrays/Collections.java b/me/smartstore/arrays/Collections.java
new file mode 100644
index 00000000..847ada31
--- /dev/null
+++ b/me/smartstore/arrays/Collections.java
@@ -0,0 +1,16 @@
+package me.smartstore.arrays;
+
+public interface Collections {
+ // 데이터를 가지고 있는 객체가 아님
+ // 구현 해야하는 메소드의 정보만 가지고 있음 (인터페이스)
+
+ int size();
+ T get(int index);
+ void set(int index, T object);
+ int indexOf(T object);
+ void add(T object);
+ void add(int index, T object);
+ T pop();
+ T pop(int index);
+ T pop(T object);
+}
diff --git a/me/smartstore/arrays/DArray.java b/me/smartstore/arrays/DArray.java
new file mode 100644
index 00000000..269bb4bc
--- /dev/null
+++ b/me/smartstore/arrays/DArray.java
@@ -0,0 +1,148 @@
+package me.smartstore.arrays;
+
+import me.smartstore.exception.ElementNotFoundException;
+import me.smartstore.exception.EmptyArrayException;
+import me.smartstore.exception.NullArgumentException;
+
+public class DArray implements Collections { // Dynamic Array
+
+ protected static final int DEFAULT = 10;
+
+ protected T[] arrays;
+ protected int size;
+ protected int capacity;
+
+ public DArray() throws ClassCastException {
+ arrays = (T[]) new Object[DEFAULT];
+ capacity = DEFAULT;
+ }
+
+ public DArray(int initial) throws ClassCastException {
+ arrays = (T[]) new Object[initial];
+ capacity = initial;
+ }
+
+ public DArray(T[] arrays) {
+ this.arrays = arrays;
+ capacity = arrays.length;
+ size = arrays.length;
+ }
+
+ /////////////////////////////////////////
+ // add, set, get, pop, indexOf, size, capacity (for dynamic-sized array)
+
+ @Override
+ public int size() {
+ return size;
+ }
+
+ // 배열에 얼마나 capacity 남아있는지 외부에 알려줄 필요가 없기 때문에 으로 정의
+ protected int capacity() {
+ return capacity;
+ }
+
+ @Override
+ public T get(int index) throws IndexOutOfBoundsException {
+ if (index < 0 || index >= size) throw new IndexOutOfBoundsException();
+ return arrays[index];
+ }
+
+ /**
+ * @param: ...
+ * @return: ...
+ * @throws: IndexOutOfBoundsException
+ * @throws: NullArgumentException
+ * */
+ @Override
+ public void set(int index, T object) throws IndexOutOfBoundsException, NullArgumentException {
+ if (index < 0 || index >= size) throw new IndexOutOfBoundsException();
+ if (object == null) throw new NullArgumentException();
+
+ arrays[index] = object;
+ }
+
+ @Override
+ public int indexOf(T object) throws NullArgumentException, ElementNotFoundException {
+ if (object == null) throw new NullArgumentException(); // not found (instead of throwing exception)
+
+ for (int i = 0; i < size; i++) {
+ if (arrays[i] == null) continue;
+ if (arrays[i].equals(object)) return i;
+ }
+ throw new ElementNotFoundException(); // not found
+ }
+
+ // 배열의 cap이 부족한 경우
+ @Override
+ public void add(T object) throws NullArgumentException {
+ if (object == null) throw new NullArgumentException(); // if argument is null, do not add null value in array
+
+ if (size < capacity) {
+ arrays[size] = object;
+ size++;
+ } else {
+ grow();
+ add(object);
+ }
+ }
+
+ @Override
+ public void add(int index, T object) throws IndexOutOfBoundsException, NullArgumentException {
+ if (index < 0 || index >= size) throw new IndexOutOfBoundsException();
+ if (object == null) throw new NullArgumentException();
+
+ if (size < capacity) {
+ for (int i = size-1; i >= index ; i--) {
+ arrays[i+1] = arrays[i];
+ }
+ arrays[index] = object;
+ size++;
+ } else {
+ grow();
+ add(index, object);
+ }
+ }
+
+ @Override
+ public T pop() {
+
+ return pop(size-1);
+ }
+
+ @Override
+ public T pop(int index) throws IndexOutOfBoundsException {
+ if (size == 0) throw new EmptyArrayException();
+ if (index < 0 || index >= size) throw new IndexOutOfBoundsException();
+
+ T popElement = arrays[index];
+ arrays[index] = null; // 삭제됨을 명시적으로 표현
+
+ for (int i = index+1; i < size; i++) {
+ arrays[i-1] = arrays[i];
+ }
+ arrays[size-1] = null;
+ size--;
+ return popElement;
+ }
+
+ @Override
+ public T pop(T object) {
+ return pop(indexOf(object));
+ }
+
+ protected void grow() {
+ capacity *= 2; // doubling
+ arrays = java.util.Arrays.copyOf(arrays, capacity);
+
+ // size는 그대로
+ }
+
+ @Override
+ public String toString() {
+ String toStr = "";
+ for (int i = 0; i < size; i++) {
+ toStr += (arrays[i] + "\n");
+ }
+ return toStr;
+ }
+}
diff --git a/me/smartstore/customer/Customer.java b/me/smartstore/customer/Customer.java
new file mode 100644
index 00000000..07807daa
--- /dev/null
+++ b/me/smartstore/customer/Customer.java
@@ -0,0 +1,108 @@
+package me.smartstore.customer;
+
+import me.smartstore.group.Group;
+
+import java.util.Objects;
+
+public class Customer {
+ private String cusName;
+ private String cusId;
+ private Integer cusTotalTime;
+ private Integer cusTotalPay;
+ private Group group; // 현재 분류 기준에 의해 각 고객을 분류된 결과
+
+
+
+ public Customer() {
+ }
+
+ public Customer(String cusId) {
+ this.cusId = cusId;
+ }
+
+ public Customer(String cusName, String cusId) {
+ this.cusName = cusName;
+ this.cusId = cusId;
+ }
+
+ public Customer(String cusName, String cusId, Integer cusTotalTime, Integer cusTotalPay) {
+ this.cusName = cusName;
+ this.cusId = cusId;
+ this.cusTotalTime = cusTotalTime;
+ this.cusTotalPay = cusTotalPay;
+ }
+
+ public Customer(String cusName, String cusId, Integer cusTotalTime, Integer cusTotalPay, Group group) {
+ this.cusName = cusName;
+ this.cusId = cusId;
+ this.cusTotalTime = cusTotalTime;
+ this.cusTotalPay = cusTotalPay;
+ this.group = group;
+ }
+
+ public String getCusName() {
+ return cusName;
+ }
+
+ public void setCusName(String cusName) {
+ this.cusName = cusName;
+ }
+
+ public String getCusId() {
+ return cusId;
+ }
+
+ public void setCusId(String cusId) {
+ this.cusId = cusId;
+ }
+
+ public Integer getCusTotalTime() {
+ return cusTotalTime;
+ }
+
+ public void setCusTotalTime(Integer cusTotalTime) {
+ this.cusTotalTime = cusTotalTime;
+ }
+
+ public Integer getCusTotalPay() {
+ return cusTotalPay;
+ }
+
+ public void setCusTotalPay(Integer cusTotalPay) {
+ this.cusTotalPay = cusTotalPay;
+ }
+
+ public Group getGroup() {
+ return group;
+ }
+
+ public void setGroup(Group 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 Objects.equals(cusId, customer.cusId);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(cusId);
+ }
+
+ @Override
+ public String toString() {
+ return "Customer{" +
+ "cusName='" + cusName + '\'' +
+ ", cusId='" + cusId + '\'' +
+ ", cusTotalTime=" + cusTotalTime +
+ ", cusTotalPay=" + cusTotalPay +
+ ", group=GroupType:" + group +
+ '}';
+ }
+}
+
+
diff --git a/me/smartstore/customer/Customers.java b/me/smartstore/customer/Customers.java
new file mode 100644
index 00000000..c6af8ded
--- /dev/null
+++ b/me/smartstore/customer/Customers.java
@@ -0,0 +1,96 @@
+package me.smartstore.customer;
+
+import me.smartstore.arrays.DArray;
+import me.smartstore.group.GroupType;
+import me.smartstore.group.Groups;
+import me.smartstore.group.Group;
+
+import java.util.Arrays;
+import java.util.Comparator;
+
+
+public class Customers extends DArray {
+ private final Groups allGroups = Groups.getInstance();
+ private static Customers allCustomers;
+
+ public static Customers getInstance() {
+ if (allCustomers == null) {
+ allCustomers = new Customers();
+ }
+ return allCustomers;
+ }
+ private Group find(int totalTime, int totalPay) {
+ try {
+ if(totalTime >= allGroups.find(GroupType.VVIP).getParameter().getMinTime() && totalPay>=allGroups.find(GroupType.VVIP).getParameter().getMinPay()){
+ return allGroups.find(GroupType.VVIP);
+ } else if (totalTime >= allGroups.find(GroupType.VIP).getParameter().getMinTime() && totalPay>=allGroups.find(GroupType.VIP).getParameter().getMinPay()) {
+ return allGroups.find(GroupType.VIP);
+ } else if (totalTime >= allGroups.find(GroupType.GENERAL).getParameter().getMinTime() && totalPay>=allGroups.find(GroupType.GENERAL).getParameter().getMinPay()) {
+ return allGroups.find(GroupType.GENERAL);
+ } else{
+ return allGroups.find(GroupType.NONE);
+ }
+ } catch (NullPointerException e){
+ return null;
+ }
+ }
+ private Customers() {}
+
+ // refresh 함수가 호출되는 경우
+ // 1. 분류기준 바뀔 때
+ // 2. 새로운 고객이 들어올 때df
+ public void refresh() {
+ for(int i=0; i() {
+ @Override
+ public int compare(Customer o1, Customer o2) {
+ return (o1.getCusName().compareTo(o2.getCusName()) * scount);
+ }
+ });
+ }
+
+ public void sortPay(Customer[] value, int scount) {
+ Arrays.sort(value, new Comparator() {
+ @Override
+ public int compare(Customer o1, Customer o2) {
+ return (o1.getCusTotalPay().compareTo(o2.getCusTotalPay()) * scount);
+ }
+ });
+ }
+
+ public void sortTime(Customer[] value, int scount) {
+ Arrays.sort(value, new Comparator() {
+ @Override
+ public int compare(Customer o1, Customer o2) {
+ return (o1.getCusTotalTime().compareTo(o2.getCusTotalTime()) * scount);
+ }
+ });
+ }
+
+}
diff --git a/me/smartstore/exception/ArrayEmptyException.java b/me/smartstore/exception/ArrayEmptyException.java
new file mode 100644
index 00000000..a142fe38
--- /dev/null
+++ b/me/smartstore/exception/ArrayEmptyException.java
@@ -0,0 +1,14 @@
+package me.smartstore.exception;
+
+import me.smartstore.util.Message;
+
+public class ArrayEmptyException extends RuntimeException {
+
+ public ArrayEmptyException() {
+ super(Message.ERR_MSG_INVALID_ARR_EMPTY);
+ }
+
+ public ArrayEmptyException(String message) {
+ super(message);
+ }
+}
\ No newline at end of file
diff --git a/me/smartstore/exception/ElementNotFoundException.java b/me/smartstore/exception/ElementNotFoundException.java
new file mode 100644
index 00000000..ac2f92fb
--- /dev/null
+++ b/me/smartstore/exception/ElementNotFoundException.java
@@ -0,0 +1,23 @@
+package me.smartstore.exception;
+
+public class ElementNotFoundException extends RuntimeException {
+ public ElementNotFoundException() {
+ }
+
+ public ElementNotFoundException(String message) {
+ super(message);
+ }
+
+ public ElementNotFoundException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ public ElementNotFoundException(Throwable cause) {
+ super(cause);
+ }
+
+ public ElementNotFoundException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
+ super(message, cause, enableSuppression, writableStackTrace);
+ }
+}
+
diff --git a/me/smartstore/exception/EmptyArrayException.java b/me/smartstore/exception/EmptyArrayException.java
new file mode 100644
index 00000000..57013a9c
--- /dev/null
+++ b/me/smartstore/exception/EmptyArrayException.java
@@ -0,0 +1,23 @@
+package me.smartstore.exception;
+
+public class EmptyArrayException extends RuntimeException {
+ public EmptyArrayException() {
+ }
+
+ public EmptyArrayException(String message) {
+ super(message);
+ }
+
+ public EmptyArrayException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ public EmptyArrayException(Throwable cause) {
+ super(cause);
+ }
+
+ public EmptyArrayException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
+ super(message, cause, enableSuppression, writableStackTrace);
+ }
+}
+
diff --git a/me/smartstore/exception/InputEmptyException.java b/me/smartstore/exception/InputEmptyException.java
new file mode 100644
index 00000000..8ea30894
--- /dev/null
+++ b/me/smartstore/exception/InputEmptyException.java
@@ -0,0 +1,14 @@
+package me.smartstore.exception;
+
+import me.smartstore.util.Message;
+
+public class InputEmptyException extends RuntimeException {
+
+ public InputEmptyException() {
+ super(Message.ERR_MSG_INVALID_INPUT_EMPTY);
+ }
+
+ public InputEmptyException(String message) {
+ super(message);
+ }
+}
\ No newline at end of file
diff --git a/me/smartstore/exception/InputEndException.java b/me/smartstore/exception/InputEndException.java
new file mode 100644
index 00000000..ffba020a
--- /dev/null
+++ b/me/smartstore/exception/InputEndException.java
@@ -0,0 +1,13 @@
+package me.smartstore.exception;
+
+import me.smartstore.util.Message;
+
+public class InputEndException extends RuntimeException {
+ public InputEndException() {
+ super(Message.ERR_MSG_INPUT_END);
+ }
+
+ public InputEndException(String message) {
+ super(message);
+ }
+}
diff --git a/me/smartstore/exception/InputFormatException.java b/me/smartstore/exception/InputFormatException.java
new file mode 100644
index 00000000..edc44e44
--- /dev/null
+++ b/me/smartstore/exception/InputFormatException.java
@@ -0,0 +1,13 @@
+package me.smartstore.exception;
+
+import me.smartstore.util.Message;
+
+public class InputFormatException extends RuntimeException {
+ public InputFormatException() {
+ super(Message.ERR_MSG_INVALID_INPUT_FORMAT);
+ }
+
+ public InputFormatException(String message) {
+ super(message);
+ }
+}
diff --git a/me/smartstore/exception/InputRangeException.java b/me/smartstore/exception/InputRangeException.java
new file mode 100644
index 00000000..10d7b011
--- /dev/null
+++ b/me/smartstore/exception/InputRangeException.java
@@ -0,0 +1,13 @@
+package me.smartstore.exception;
+
+import me.smartstore.util.Message;
+
+public class InputRangeException extends RuntimeException {
+ public InputRangeException() {
+ super(Message.ERR_MSG_INVALID_INPUT_RANGE);
+ }
+
+ public InputRangeException(String message) {
+ super(message);
+ }
+}
diff --git a/me/smartstore/exception/InputTypeException.java b/me/smartstore/exception/InputTypeException.java
new file mode 100644
index 00000000..d0d9c745
--- /dev/null
+++ b/me/smartstore/exception/InputTypeException.java
@@ -0,0 +1,13 @@
+package me.smartstore.exception;
+
+import me.smartstore.util.Message;
+
+public class InputTypeException extends RuntimeException {
+ public InputTypeException() {
+ super(Message.ERR_MSG_INVALID_INPUT_TYPE);
+ }
+
+ public InputTypeException(String message) {
+ super(message);
+ }
+}
\ No newline at end of file
diff --git a/me/smartstore/exception/NullArgumentException.java b/me/smartstore/exception/NullArgumentException.java
new file mode 100644
index 00000000..e2a8531d
--- /dev/null
+++ b/me/smartstore/exception/NullArgumentException.java
@@ -0,0 +1,22 @@
+package me.smartstore.exception;
+
+public class NullArgumentException extends RuntimeException {
+ public NullArgumentException() {
+ }
+
+ public NullArgumentException(String message) {
+ super(message);
+ }
+
+ public NullArgumentException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ public NullArgumentException(Throwable cause) {
+ super(cause);
+ }
+
+ public NullArgumentException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
+ super(message, cause, enableSuppression, writableStackTrace);
+ }
+}
diff --git a/me/smartstore/group/Group.java b/me/smartstore/group/Group.java
new file mode 100644
index 00000000..bbffe1ab
--- /dev/null
+++ b/me/smartstore/group/Group.java
@@ -0,0 +1,53 @@
+package me.smartstore.group;
+
+import java.util.Objects;
+
+public class Group {
+ private Parameter parameter; // 분류기준
+ private GroupType groupType; // 그룹 타입
+
+ public Group() {
+ }
+
+ public Group(Parameter parameter, GroupType groupType) {
+ this.parameter = parameter;
+ this.groupType = groupType;
+ }
+
+ public Parameter getParameter() {
+ return parameter;
+ }
+
+ public void setParameter(Parameter parameter) {
+ this.parameter = parameter;
+ }
+
+ public GroupType getGroupType() {
+ return groupType;
+ }
+
+ public void setGroupType(GroupType groupType) {
+ this.groupType = groupType;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ Group group = (Group) o;
+ return Objects.equals(parameter, group.parameter) && groupType == group.groupType;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(parameter, groupType);
+ }
+
+ @Override
+ public String toString() {
+ return "Group{" +
+ "parameter=" + parameter +
+ ", groupType=" + groupType +
+ '}';
+ }
+}
diff --git a/me/smartstore/group/GroupType.java b/me/smartstore/group/GroupType.java
new file mode 100644
index 00000000..d6ccca37
--- /dev/null
+++ b/me/smartstore/group/GroupType.java
@@ -0,0 +1,22 @@
+package me.smartstore.group;
+
+public enum GroupType {
+ NONE("해당없음"), GENERAL("일반고객"), VIP("우수고객"), VVIP("최우수고객"),
+ N("해당없음"), G("일반고객"), V("우수고객"), VV("최우수고객");
+
+
+ String groupType = "";
+
+
+ GroupType(String groupType) {
+ this.groupType = groupType;
+ }
+
+ public GroupType replaceFullName() {
+ if (this == N) return NONE;
+ else if (this == G) return GENERAL;
+ else if (this == V) return VIP;
+ else if (this == VV) return VVIP;
+ return this;
+ }
+}
diff --git a/me/smartstore/group/Groups.java b/me/smartstore/group/Groups.java
new file mode 100644
index 00000000..5a986414
--- /dev/null
+++ b/me/smartstore/group/Groups.java
@@ -0,0 +1,31 @@
+package me.smartstore.group;
+
+import me.smartstore.arrays.DArray;
+
+public class Groups extends DArray {
+ // singleton
+ private static Groups allGroups;
+
+ public static Groups getInstance() {
+ if (allGroups == null) {
+ allGroups = new Groups();
+ }
+ return allGroups;
+ }
+
+ private Groups() {}
+
+ public Group find(GroupType groupType) {
+ for (int i = 0; i < this.size; i++) {
+ if (this.get(i).getGroupType() == groupType) {
+ return this.get(i);
+ }
+ }
+
+ return null;
+ }
+
+
+}
+
+
diff --git a/me/smartstore/group/Parameter.java b/me/smartstore/group/Parameter.java
new file mode 100644
index 00000000..114db37a
--- /dev/null
+++ b/me/smartstore/group/Parameter.java
@@ -0,0 +1,55 @@
+package me.smartstore.group;
+
+import java.util.Objects;
+
+public class Parameter {
+ private Integer minTime;
+ private Integer minPay;
+
+
+ public Parameter() {
+ }
+
+ public Parameter(Integer minTime, Integer minPay) {
+ this.minTime = minTime;
+ this.minPay = minPay;
+ }
+
+ public Integer getMinTime() {
+ return minTime;
+ }
+
+ public void setMinTime(Integer minTime) {
+ this.minTime = minTime;
+ }
+
+ public Integer getMinPay() {
+ return minPay;
+ }
+
+ public void setMinPay(Integer minPay) {
+ this.minPay = minPay;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ Parameter parameter = (Parameter) o;
+ return Objects.equals(minTime, parameter.minTime) && Objects.equals(minPay, parameter.minPay);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(minTime, minPay);
+ }
+
+ @Override
+ public String toString() {
+ return "Parameter{" +
+ "minTime=" + minTime +
+ ", minPay=" + minPay +
+ '}';
+ }
+}
+
diff --git a/me/smartstore/menu/CustomerMenu.java b/me/smartstore/menu/CustomerMenu.java
new file mode 100644
index 00000000..29f371e0
--- /dev/null
+++ b/me/smartstore/menu/CustomerMenu.java
@@ -0,0 +1,162 @@
+package me.smartstore.menu;
+
+import me.smartstore.customer.Customer;
+import me.smartstore.customer.Customers;
+import me.smartstore.exception.EmptyArrayException;
+import me.smartstore.exception.InputEmptyException;
+import me.smartstore.exception.InputEndException;
+import me.smartstore.util.Message;
+
+import java.util.InputMismatchException;
+
+public class CustomerMenu implements Menu {
+ // singleton
+ private final Customers allCustomers = Customers.getInstance();
+ private static CustomerMenu customerMenu;
+
+ public static CustomerMenu getInstance() {
+ if (customerMenu == null) {
+ customerMenu = new CustomerMenu();
+ }
+ return customerMenu;
+ }
+
+ private CustomerMenu() {
+ }
+
+ @Override
+ public void manage() {
+ while (true) { // 서브 메뉴 페이지를 유지하기 위한 while
+ int choice = chooseMenu(new String[]{
+ "Add Customer",
+ "View Customer",
+ "Update Customer",
+ "Delete Customer",
+ "Back"});
+
+ if (choice == 1) addCustomer();
+ else if (choice == 2)
+ viewCustomer();
+ else if (choice == 3)
+ updateCustomer();
+ else if (choice == 4)
+ deleteCustomer();
+ else break; // choice == 4
+ }
+ }
+
+
+ private Customer setCustomer(Customer customer) {
+ while (true) {
+ try {
+ int choice = customerMenu.chooseMenu(new String[]{
+ "Customer Name",
+ "Customer ID",
+ "Customer Spent Time",
+ "Customer Total Pay",
+ "Back"
+ });
+
+ if (choice == 1) {
+ System.out.println("Input Customer's Name: ");
+ customer.setCusName(nextLine(Message.END_MSG));
+
+ } else if (choice == 2) {
+ System.out.println("Input Customer's ID: ");
+ customer.setCusId(nextLine(Message.END_MSG));
+ } else if (choice == 3) {
+ System.out.println("Input Customer's Spent Time: ");
+ customer.setCusTotalTime(Integer.valueOf(nextLine(Message.END_MSG)));
+ } else if (choice == 4) {
+ System.out.println("Input Customer's Total Payment: ");
+ customer.setCusTotalPay(Integer.valueOf((nextLine(Message.END_MSG))));
+ } else
+ break;
+
+ } catch (InputMismatchException e) {
+ System.out.println(Message.ERR_MSG_INVALID_INPUT_TYPE);
+ } catch (InputEndException e) {
+ System.out.println(Message.ERR_MSG_INPUT_END);
+ }
+ }
+ return customer;
+ }
+
+
+ private void addCustomer() {
+ while (true) {
+ try {
+ System.out.println("How many customer to input?");
+ int customers = Integer.parseInt(nextLine(Message.END_MSG));
+
+ for (int i = 0; i < customers; i++) {
+ System.out.println("\n====== Customer " + (i + 1) + " Info. ======");
+ Customer sCustomer = new Customer();
+ sCustomer = setCustomer(sCustomer);
+ allCustomers.add(sCustomer);
+ allCustomers.refresh();
+ }
+ return;
+ } catch (InputEndException e) {
+ System.out.println(Message.ERR_MSG_INPUT_END);
+ } catch (NumberFormatException e) {
+ System.out.println(Message.ERR_MSG_INVALID_INPUT_FORMAT);
+ }
+
+ }
+ }
+
+
+ private void viewCustomer() {
+
+ try {
+ System.out.println("\n======= Customer Info. =======");
+ for (int i = 0; i < allCustomers.size(); i++) {
+ System.out.print("NO. " + (i + 1) + "=> ");
+ System.out.println(allCustomers.get(i));
+ }
+ allCustomers.refresh();
+
+ } catch (EmptyArrayException e) {
+ System.out.println(Message.ERR_MSG_NULL_ARR_ELEMENT);
+ } catch (InputEndException e) {
+ System.out.println(Message.ERR_MSG_INPUT_END);
+ }
+ }
+
+ private void updateCustomer () {
+ viewCustomer();
+ try{
+ System.out.print("Which customer ( 1 ~ " + allCustomers.size() + " )? ");
+ int cusNum = Integer.parseInt(nextLine(Message.END_MSG));
+ setCustomer(allCustomers.get(cusNum -1) );
+ allCustomers.refresh();
+
+ }catch(InputMismatchException e){
+ System.out.println(Message.ERR_MSG_INVALID_INPUT_FORMAT);
+ }catch(InputEndException e){
+ System.out.println(Message.ERR_MSG_INPUT_END);
+ }
+ }
+
+ private void deleteCustomer () {
+ viewCustomer();
+ try{
+ System.out.print("Which customer ( 1 ~ " + allCustomers.size() + " )? ");
+ int cusNum = Integer.parseInt(nextLine(Message.END_MSG));
+
+ System.out.println(allCustomers.pop(cusNum - 1));
+ allCustomers.refresh();
+ viewCustomer();
+
+
+ }catch(InputMismatchException e){
+ System.out.println(Message.ERR_MSG_INVALID_INPUT_FORMAT);
+ }catch(InputEndException e){
+ System.out.println(Message.ERR_MSG_INPUT_END);
+ }
+
+
+
+ }
+}
diff --git a/me/smartstore/menu/GroupMenu.java b/me/smartstore/menu/GroupMenu.java
new file mode 100644
index 00000000..07f40463
--- /dev/null
+++ b/me/smartstore/menu/GroupMenu.java
@@ -0,0 +1,153 @@
+package me.smartstore.menu;
+
+import me.smartstore.customer.Customers;
+import me.smartstore.exception.InputEndException;
+import me.smartstore.group.Group;
+import me.smartstore.group.GroupType;
+import me.smartstore.group.Groups;
+import me.smartstore.group.Parameter;
+import me.smartstore.util.Message;
+import java.util.Scanner;
+
+
+public class GroupMenu implements Menu {
+ Scanner sc = new Scanner(System.in);
+
+ private final Groups allGroups = Groups.getInstance();
+ private final Customers allCustomers = Customers.getInstance();
+ // singleton
+ private static GroupMenu groupMenu;
+
+ public static GroupMenu getInstance() {
+ if (groupMenu == null) {
+ groupMenu = new GroupMenu();
+ }
+ return groupMenu;
+ }
+
+ private GroupMenu() {}
+
+ @Override
+ public void manage() {
+ while ( true ) { // 서브 메뉴 페이지를 유지하기 위한 while
+ int choice = chooseMenu(new String[]{
+ "Set Parameter",
+ "View Parameter",
+ "Update Parameter",
+ "Back"});
+
+ if (choice == 1) setParameter();
+ else if (choice == 2) { viewParameter(); }
+ else if (choice == 3) { updateParameter();}
+ //else if (choice == 4) {MainMenu.getInstance().manage();}
+ else break; // choice == 4
+ }
+
+ }
+
+ public GroupType chooseGroup() {
+ while ( true ) {
+ try {
+ System.out.println("Which group (GENERAL (G), VIP (V), VVIP (VV))? ");
+ String choice = nextLine(Message.END_MSG);
+ // group (str) -> GroupType (enum)
+ // "VIP" -> GroupType.VIP
+
+ GroupType groupType = GroupType.valueOf(choice).replaceFullName();
+ return groupType;
+ } catch (InputEndException e) {
+ System.out.println(Message.ERR_MSG_INPUT_END);
+ return null;
+ } catch (IllegalArgumentException e) {
+ System.out.println(Message.ERR_MSG_INVALID_INPUT_RANGE);
+ }
+ }
+ }
+
+ public void setParameter() { // 초기화할 때만 호출 가능
+ while ( true ) {
+
+ GroupType groupType = chooseGroup();
+ if (groupType == null) { // InputEndException 발생 시 GroupMenu으로 이동
+ break;
+ }
+ // GroupType에 해당하는 group 객체를 찾아야 함
+ Group group = allGroups.find(groupType);
+ if (group != null && group.getParameter() != null) { // group.getParameter()이 null이 아니면 이미 초기화됨
+ System.out.println("\n" + group.getGroupType() + " group already exists.");
+ System.out.println("\n" + group);
+ } else {
+ Parameter parameter = new Parameter();
+ setPaywithTime(allGroups.find(groupType).getParameter());
+
+ group.setParameter(parameter);
+ allCustomers.refresh(); // 파라미터가 변경되었거나 추가되는 경우, 고객 분류를 다시 해야함
+ }
+ }
+ }
+
+ public void setPaywithTime(Parameter parameter) { //
+ while(true) {
+ int choice = chooseMenu(new String[]{
+ "Minimum Spent Time",
+ "Minimum Total Pay",
+ "Back",
+ });
+ if (choice == 1) {
+ System.out.println("Input Minimum Spent Time:");
+ String input = nextLine(Message.END_MSG);
+ if (input.equalsIgnoreCase("end")) {
+ System.out.println(Message.ERR_MSG_INPUT_END);
+ break;
+ }
+ try {
+ parameter.setMinTime(Integer.valueOf(input));
+ } catch (NumberFormatException e) {
+ System.out.println("Invalid input. Please enter a valid number or 'end'.");
+ }
+ allCustomers.refresh();
+ }
+ else if (choice == 2) {
+ System.out.println("Input Minimum Total Pay:");
+ String input = nextLine(Message.END_MSG);
+ if (input.equalsIgnoreCase("end")) {
+ System.out.println(Message.ERR_MSG_INPUT_END);
+ break;
+ }
+ try {
+ parameter.setMinPay(Integer.valueOf(input));
+ } catch (NumberFormatException e) {
+ System.out.println("Invalid input. Please enter a valid number or 'end'.");
+ }
+ allCustomers.refresh();
+ }else
+ break;
+ }
+
+ }
+
+
+
+ public void viewParameter() {
+ while (true) {
+ GroupType groupType = chooseGroup();
+ if (groupType == null) { //end입력시 이동
+ break;
+ }
+ Group group = allGroups.find(groupType);
+ System.out.println("GroupType: " + groupType);
+ System.out.println("Parameter: " + group.getParameter());
+
+
+ }
+ }
+
+ public void updateParameter() {
+ while(true) {
+ GroupType groupType = chooseGroup();
+ if(groupType ==null) break;
+ setPaywithTime(allGroups.find(groupType).getParameter());
+ allCustomers.refresh();
+ }
+ }
+}
diff --git a/me/smartstore/menu/MainMenu.java b/me/smartstore/menu/MainMenu.java
new file mode 100644
index 00000000..a7768657
--- /dev/null
+++ b/me/smartstore/menu/MainMenu.java
@@ -0,0 +1,39 @@
+package me.smartstore.menu;
+
+public class MainMenu implements Menu {
+
+ private final CustomerMenu customerMenu = CustomerMenu.getInstance();
+ private final GroupMenu groupMenu = GroupMenu.getInstance();
+ private final SummaryMenu summaryMenu = SummaryMenu.getInstance();
+
+ // singleton
+ private static MainMenu mainMenu;
+
+ public static MainMenu getInstance() {
+ if (mainMenu == null) {
+ mainMenu = new MainMenu();
+ }
+ return mainMenu;
+ }
+
+ private MainMenu() {}
+
+ @Override
+ public void manage() {
+ while ( true ) { // 프로그램 실행 while
+ int choice = mainMenu.chooseMenu(new String[] {
+ "Parameter",
+ "Customer",
+ "Classification Summary",
+ "Quit"});
+
+ if (choice == 1) groupMenu.manage();
+ else if (choice == 2) customerMenu.manage();
+ else if (choice == 3) summaryMenu.manage();
+ else { // choice == 4
+ System.out.println("Program Finished");
+ break;
+ }
+ }
+ }
+}
diff --git a/me/smartstore/menu/Menu.java b/me/smartstore/menu/Menu.java
new file mode 100644
index 00000000..d4f7e29a
--- /dev/null
+++ b/me/smartstore/menu/Menu.java
@@ -0,0 +1,48 @@
+package me.smartstore.menu;
+
+import me.smartstore.exception.InputEndException;
+import me.smartstore.exception.InputRangeException;
+import me.smartstore.util.Message;
+
+import java.util.InputMismatchException;
+import java.util.Scanner;
+
+public interface Menu {
+ Scanner scanner = new Scanner(System.in);
+
+ default String nextLine() { // 하나의 프로그램 상에서 nextLine() 함수를 통해서 사용자 입력을 받음
+ return scanner.nextLine().toUpperCase();
+ }
+
+ default String nextLine(String end) {
+ System.out.println("** Press 'end', if you want to exit! **");
+ String str = scanner.nextLine().toUpperCase();
+ if (str.equals(end)) throw new InputEndException();
+ return str;
+ }
+
+ default int chooseMenu(String[] menus) {
+ while ( true ) { // 예외 복구 while
+ try {
+ System.out.println("===============================");
+ for (int i = 0; i < menus.length; i++) {
+ System.out.printf(" %d. %s\n", i + 1, menus[i]);
+ }
+ System.out.println("===============================");
+ System.out.print("Choose One: ");
+ int choice = Integer.parseInt(nextLine());
+ if (choice >= 1 && choice <= menus.length) return choice;
+ throw new InputRangeException(); // choice 가 범위에 벗어남
+
+ } catch (InputMismatchException e) {
+ System.out.println(Message.ERR_MSG_INVALID_INPUT_FORMAT);
+
+ } catch (InputRangeException e) {
+ System.out.println(Message.ERR_MSG_INVALID_INPUT_RANGE);
+
+ }
+ }
+ }
+
+ void manage(); // 각 서브메뉴들을 관리하는 함수 (각 서브메뉴의 최상위 메뉴)
+}
diff --git a/me/smartstore/menu/SummaryMenu.java b/me/smartstore/menu/SummaryMenu.java
new file mode 100644
index 00000000..c4ba933d
--- /dev/null
+++ b/me/smartstore/menu/SummaryMenu.java
@@ -0,0 +1,128 @@
+package me.smartstore.menu;
+
+import me.smartstore.customer.Customer;
+import me.smartstore.customer.Customers;
+import me.smartstore.exception.InputEndException;
+import me.smartstore.exception.InputRangeException;
+import me.smartstore.group.Group;
+import me.smartstore.group.Groups;
+import me.smartstore.util.Message;
+
+public class SummaryMenu implements Menu {
+
+ private final Customers allCustomers = Customers.getInstance();
+ private final Groups allGroups = Groups.getInstance();
+ private static SummaryMenu summaryMenu;
+
+ public static SummaryMenu getInstance() {
+ if (summaryMenu == null) {
+ summaryMenu = new SummaryMenu();
+ }
+ return summaryMenu;
+ }
+
+ private SummaryMenu() {
+ }
+
+ @Override
+ public void manage() {
+ while (true) { // 서브 메뉴 페이지를 유지하기 위한 while
+ int choice = chooseMenu(new String[]{
+ "Summary",
+ "Summary (Sorted By Name)",
+ "Summary (Sorted By Time)",
+ "Summary (Sorted By Pay)",
+ "Back"});
+ if (choice == 1) summary();
+ else if (choice == 2) summaryByName();
+ else if (choice == 3) summaryByTime();
+ else if (choice == 4) summaryByPay();
+ else break; // choice == 4
+ }
+ }
+
+ private void show(Customer[] customers, Group group) {
+ try {
+ System.out.println("==============================");
+ System.out.printf("Group : %s ( Time : %d, Pay : %d )\n", group.getGroupType(),
+ group.getParameter().getMinTime(),
+ group.getParameter().getMinPay());
+ System.out.println("==============================");
+ for (int i = 0; i < customers.length; i++) {
+ System.out.println("NO.\t" + (i + 1) + " => " + customers[i]);
+ }
+ System.out.println("==============================");
+ System.out.println();
+
+
+ } catch (NullPointerException e) {
+ System.out.println("그룹을 찾을 수 없다");
+ }
+ }
+
+ private int sortType() {
+ while (true) {
+ try {
+ System.out.println("Which order (ASCENDING (A), DESCENDING (D))?");
+ String choice = nextLine(Message.END_MSG);
+
+ if (!choice.equals("A") && !choice.equals("D") && !choice.equals("a") && !choice.equals("d")) {
+ throw new InputRangeException();
+ }
+
+ if (choice.equals("a") || choice.equals("A")) return 1;
+ else return -1;
+
+ } catch (InputEndException e) {
+ System.out.println(Message.ERR_MSG_INPUT_END);
+ } catch (InputRangeException e) {
+ System.out.println(Message.ERR_MSG_INVALID_INPUT_RANGE);
+ }
+ }
+ }
+
+
+
+ private void summary() {
+ int mark = 0;
+ for(int i = 0; i < allGroups.size(); i++) {
+ Customer[] value = allCustomers.seperateGroup(allGroups.get(i).getGroupType());
+ show(value, allGroups.get(i));
+ }
+ }
+
+ private void summaryByName() {
+ int sortcount = 0;
+ sortcount = sortType();
+ for(int i = 0; i < allGroups.size(); i++){
+ Customer[] value = allCustomers.seperateGroup(allGroups.get(i).getGroupType());
+ allCustomers.sortName(value, sortcount);
+ show(value, allGroups.get(i));
+ }
+ }
+
+ private void summaryByTime() {
+ int sortcount = 0;
+ sortcount = sortType();
+ for (int i = 0; i < allGroups.size(); i++) {
+ Customer[] value = allCustomers.seperateGroup(allGroups.get(i).getGroupType());
+ allCustomers.sortTime(value, sortcount);
+ show(value, allGroups.get(i));
+ }
+
+ }
+
+ private void summaryByPay() {
+ int sortcount = 0;
+ sortcount = sortType();
+ for (int i = 0; i < allGroups.size(); i++) {
+ Customer[] value = allCustomers.seperateGroup(allGroups.get(i).getGroupType());
+ allCustomers.sortPay(value, sortcount);
+ show(value, allGroups.get(i));
+ }
+
+ }
+}
+
+
+
diff --git a/me/smartstore/util/Message.java b/me/smartstore/util/Message.java
new file mode 100644
index 00000000..1c67d21e
--- /dev/null
+++ b/me/smartstore/util/Message.java
@@ -0,0 +1,13 @@
+package me.smartstore.util;
+
+public interface Message {
+ String ERR_MSG_INVALID_ARR_EMPTY = "No Customers. Please input one first.";
+ String ERR_MSG_NULL_ARR_ELEMENT = "Elements in Array has null. Array can't be sorted.";
+ String ERR_MSG_INVALID_INPUT_NULL = "Null Input. Please input something.";
+ String ERR_MSG_INVALID_INPUT_EMPTY = "Empty Input. Please input something.";
+ String ERR_MSG_INVALID_INPUT_RANGE = "Invalid Input. Please try again.";
+ String ERR_MSG_INVALID_INPUT_TYPE = "Invalid Type for Input. Please try again.";
+ String ERR_MSG_INVALID_INPUT_FORMAT = "Invalid Format for Input. Please try again.";
+ String ERR_MSG_INPUT_END = "END is pressed. Exit this menu.";
+ String END_MSG = "END";
+}