diff --git a/ToyProject/src/me/smartstore/Main.java b/ToyProject/src/me/smartstore/Main.java new file mode 100644 index 00000000..f7bc3acf --- /dev/null +++ b/ToyProject/src/me/smartstore/Main.java @@ -0,0 +1,7 @@ +package me.smartstore; + +public class Main { + public static void main(String[] args) { + SmartStoreApp.getInstance().run(); // function chaining + } +} diff --git a/ToyProject/src/me/smartstore/SmartStoreApp.java b/ToyProject/src/me/smartstore/SmartStoreApp.java new file mode 100644 index 00000000..5613b115 --- /dev/null +++ b/ToyProject/src/me/smartstore/SmartStoreApp.java @@ -0,0 +1,87 @@ +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.MainMenu; + +public class SmartStoreApp { + + private final Groups allGroups = Groups.getInstance(); + private final Customers allCustomers = Customers.getInstance(); + private final MainMenu mainMenu = MainMenu.getInstance(); + + private static SmartStoreApp smartStoreApp; + + // singletone pattern + 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.00"); + System.out.println(" Copyright 2023 JeonghoSong All rights reserved."); + System.out.println("===========================================\n"); + } + + public SmartStoreApp test() { + allGroups.add(new Group(new Parameter(0, 0), GroupType.NONE)); + 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++) { + int spentTime = ((int) (Math.random() * 5) + 1) * 10; + int totalPay = ((int) (Math.random() * 5) + 1) * 100000; + +// Group customerGroup = allGroups.getGroupByParameter(spentTime, totalPay); + +// 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)); + +// allCustomers.add(new Customer( +// Character.toString( +// (char) ('a' + i) + "123", +// spentTime, +// totalPay, +// customerGroup +// ) +// )); + +// // 마지막 사용하던 코드 +// allCustomers.add(new Customer( +// Character.toString( +// (char) ('a' + i)), +// (char) ('a' + i) + "123", +// spentTime, +// totalPay, +// customerGroup)); + } + + System.out.println("allCustomers = " + allCustomers); + System.out.println("allGroups = " + allGroups); + + return this; + } + + public void run() { + details(); + mainMenu.manage(); + } + +} diff --git a/ToyProject/src/me/smartstore/arrays/Collections.java b/ToyProject/src/me/smartstore/arrays/Collections.java new file mode 100644 index 00000000..e7335d9f --- /dev/null +++ b/ToyProject/src/me/smartstore/arrays/Collections.java @@ -0,0 +1,14 @@ +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); + void extend(); +} diff --git a/ToyProject/src/me/smartstore/arrays/DArray.java b/ToyProject/src/me/smartstore/arrays/DArray.java new file mode 100644 index 00000000..2b7530ee --- /dev/null +++ b/ToyProject/src/me/smartstore/arrays/DArray.java @@ -0,0 +1,142 @@ +package me.smartstore.arrays; + +import me.smartstore.exception.EmptyArrayException; +import me.smartstore.group.Group; +import me.smartstore.util.Message; + +import java.util.Arrays; +import java.util.Iterator; +import java.util.Objects; +import java.util.stream.IntStream; + +import static java.util.Arrays.copyOf; + +public class DArray implements Collections { + + protected static final int DEFAULT = 10; + + protected T[] arrays; + protected int size; + protected int capacity; + + /** + * ClassCastException 예외 던지는 이유 + * DArray Constructor에서 T타입이 Object 타입으로 캐스팅되는 과정에서 발생 가능 + * + * 즉, T타입이 Object 타입과 호환되지 않아서 ClassCastException 예외 발생 가능 + */ + public DArray() throws ClassCastException { + arrays = (T[]) new Object[DEFAULT]; + capacity = DEFAULT; + } + + public DArray(int initial) throws ClassCastException { + arrays = (T[]) new Object[initial]; + capacity = initial; + } + + /** + * ClassCastException 안 던지는 이유 + * T[] 배열을 이미 파라미터로 직접 전달 받음 > 예외 발생 가능성 없음 + */ + public DArray(T[] arrays) { + this.arrays = arrays; + capacity = arrays.length; + size = arrays.length; + } + + @Override + public int size() { + return size; + } + + /** + * + * @param index + * @return + * @throws IndexOutOfBoundsException + * + * 예외 처리를 두 번 해주는 이유 + * 메서드 호출자가 index value를 잘못 전달할 경우 걸러지지 않음. + * if문 안에서는 인덱스 값이 유효하지 않은 경우에 대한 예외 처리 담당 + */ + @Override + public T get(int index) throws IndexOutOfBoundsException { + if (index < 0 || index >= size) throw new IndexOutOfBoundsException(); + return arrays[index]; + } + + @Override + public void set(int index, T object) { + + } + + @Override + public int indexOf(T object) { + return 0; + } + + @Override + public void add(T object) { +// if (object == null) { +// throw new +// } + if (size < capacity) { + arrays[size] = object; + size++; + } else { + extend(); + add(object); + } + } + + @Override + public void add(int index, T object) { + + } + + @Override + public T pop() { + return null; + } + + @Override + public T pop(int index) throws EmptyArrayException, IndexOutOfBoundsException { + if (size==0) throw new EmptyArrayException(Message.ERR_MSG_ARR_EMPTY); + if (index < 0 || index > size) throw new IndexOutOfBoundsException(Message.ERR_MSG_ARR_OUT_OF_BOUNDARY); + T item = arrays[index]; + for (int i = index; i < size; i++) { + arrays[i] = arrays[i+1]; + } + size--; + return item; + } + +// public boolean isEmpty() { +// +// } + + @Override + public T pop(T object) throws EmptyArrayException { + return pop(size-1); + } + + /** + * 목적 : 리스트의 capacity가 모자랄 경우, *2만큼 증분하여 리스트 길이를 증가 + */ + @Override + public void extend() { + capacity *= 2; + arrays = copyOf(arrays, capacity); + } + + +// @Override +// public Iterator iterator() { +// return IntStream.range(0, size) +// .mapToObj(i -> arrays[i]) +// .iterator(); +// } + + +} diff --git a/ToyProject/src/me/smartstore/customer/Customer.java b/ToyProject/src/me/smartstore/customer/Customer.java new file mode 100644 index 00000000..58ead3cb --- /dev/null +++ b/ToyProject/src/me/smartstore/customer/Customer.java @@ -0,0 +1,93 @@ +package me.smartstore.customer; + +import me.smartstore.group.Group; +import me.smartstore.group.Groups; + +public class Customer { + private String customerName; + private String customerId; + private Integer customerTotalTime; + private Integer customerTotalPay; + private Group group; // 분류 기준에 따라 고객을 분류한 결과 + + public Customer() { + } + + public Customer(String customerId) { + this.customerId = customerId; + } + + public Customer(String customerName, String customerId) { + this.customerName = customerName; + this.customerId = customerId; + } + + public Customer(String customerName, String customerId, Integer customerTotalTime, Integer customerTotalPay) { + this.customerName = customerName; + this.customerId = customerId; + this.customerTotalTime = customerTotalTime; + this.customerTotalPay = customerTotalPay; + } + + public Customer(String customerName, String customerId, Integer customerTotalTime, Integer customerTotalPay, Group group) { + this.customerName = customerName; + this.customerId = customerId; + this.customerTotalTime = customerTotalTime; + this.customerTotalPay = customerTotalPay; + } + + public void getCustomerInfo() { + + } + + public String getCustomerName() { + return customerName; + } + + public void setCustomerName(String customerName) { + this.customerName = customerName; + } + + public String getCustomerId() { + return customerId; + } + + public void setCustomerId(String customerId) { + this.customerId = customerId; + } + + public Integer getCustomerTotalTime() { + return customerTotalTime; + } + + public void setCustomerTotalTime(Integer customerTotalTime) { + this.customerTotalTime = customerTotalTime; + } + + public Integer getCustomerTotalPay() { + return customerTotalPay; + } + + public void setCustomerTotalPay(Integer customerTotalPay) { + this.customerTotalPay = customerTotalPay; + } + + public Group getGroup() { + return group; + } + + public void setGroup(Group group) { + this.group = group; + } + + @Override + public String toString() { + return "Customer{" + + "customerName='" + customerName + '\'' + + ", customerId='" + customerId + '\'' + + ", customerTotalTime=" + customerTotalTime + + ", customerTotalPay=" + customerTotalPay + + ", group=" + group + + '}'; + } +} diff --git a/ToyProject/src/me/smartstore/customer/Customers.java b/ToyProject/src/me/smartstore/customer/Customers.java new file mode 100644 index 00000000..20786cd3 --- /dev/null +++ b/ToyProject/src/me/smartstore/customer/Customers.java @@ -0,0 +1,87 @@ +package me.smartstore.customer; + +import me.smartstore.arrays.DArray; +import me.smartstore.group.Group; +import me.smartstore.group.GroupType; +import me.smartstore.group.Groups; + +import java.util.Arrays; +import java.util.Comparator; + +import static me.smartstore.group.GroupType.getGroupTypeLevel; + +public class Customers extends DArray { + + private static Customers allCustomers; + private final Groups allGroups; + + public static Customers getInstance() { + if (allCustomers == null) { + allCustomers = new Customers(); + } + return allCustomers; + } + + private Customers() { + this.allGroups = Groups.getInstance(); + } + + /** + * 고객 추가 및 고객 분류기준 변경시 고객 분류 등급 재조정 해주는 역할 담당 + */ + public void refresh() { + for (int i=0; i< allCustomers.size(); i++) { + Customer customer = allCustomers.get(i); + System.out.println("refresh start -> allCustomer size configure : " + allCustomers.size()); + Group group = findGroupOfCustomer(customer.getCustomerTotalTime(), customer.getCustomerTotalPay()); + customer.setGroup(group); + } + } + + /** + * @param: spentTime + * @param: spentMoney + * @return: Group instance that corresponding with customer + */ + public Group findGroupOfCustomer(int spentTime, int spentMoney) { + Group group = allGroups.get(0); + for (int i=1; i< allGroups.size(); i++) { + Group pickedGroup = allGroups.get(i); + int minSpentTime = pickedGroup.getParameter().getMinTime(); + int minSpentMoney = pickedGroup.getParameter().getMinPay(); + if (spentTime>=minSpentTime && spentMoney>=minSpentMoney) { + if (getGroupTypeLevel(group) < getGroupTypeLevel(pickedGroup)) { + group = pickedGroup; + } + } + } + return group; + } + + public Customer[] getAllCustomers() { + Customer[] customers = new Customer[size]; + for (int i=0; i comparator) { + Customer[] customers = getAllCustomers(); + Arrays.sort(customers, comparator); + return customers; + } + + // public void refresh(Groups groups) { +// for (Customer customer : arrays) { +// Group group = groups.find(GroupType) +// } +// } + + // 파라미터가 변경되었거나 추가되는 경우, 고객 분류를 다시 해야함 +// public void refresh(Groups groups) { +// for (Customer customer : ) { +// Group group = groups.find +// } +// } +} diff --git a/ToyProject/src/me/smartstore/exception/EmptyArrayException.java b/ToyProject/src/me/smartstore/exception/EmptyArrayException.java new file mode 100644 index 00000000..769b0d81 --- /dev/null +++ b/ToyProject/src/me/smartstore/exception/EmptyArrayException.java @@ -0,0 +1,14 @@ +package me.smartstore.exception; + +import me.smartstore.util.Message; + +public class EmptyArrayException extends RuntimeException { + + public EmptyArrayException() { + super(Message.ERR_MSG_ARR_EMPTY); + } + + public EmptyArrayException(String message) { + super(message); + } +} diff --git a/ToyProject/src/me/smartstore/exception/InputEndException.java b/ToyProject/src/me/smartstore/exception/InputEndException.java new file mode 100644 index 00000000..fe1e3024 --- /dev/null +++ b/ToyProject/src/me/smartstore/exception/InputEndException.java @@ -0,0 +1,17 @@ +package me.smartstore.exception; + +import me.smartstore.util.Message; + +/** + * super()를 호출하는 이유 + * + * util.Message 인터페이스에서 ERR_MSG_INPUT_END 상수 선언 + * 이 클래스의 생성자가 호출되면 RuntimeException 클래스의 생성자를 호출하게 됨. + * 이때 super(Message.ERR_MSG_INPUT_END)가 실행 > Message 인터페이스의 ERR_MSG_INPUT_END 상수 값을 인자로 전달 + * 이후 RuntimeException의 생성자가 Message.ERR_MSG_INPUT_END 값을 포함한 예외 객체를 생성하여 반환함. + */ +public class InputEndException extends RuntimeException { + public InputEndException() { + super(Message.ERR_MSG_INPUT_END); + } +} diff --git a/ToyProject/src/me/smartstore/exception/InputRangeException.java b/ToyProject/src/me/smartstore/exception/InputRangeException.java new file mode 100644 index 00000000..10d7b011 --- /dev/null +++ b/ToyProject/src/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/ToyProject/src/me/smartstore/exception/InvalidSortTypeException.java b/ToyProject/src/me/smartstore/exception/InvalidSortTypeException.java new file mode 100644 index 00000000..173a2580 --- /dev/null +++ b/ToyProject/src/me/smartstore/exception/InvalidSortTypeException.java @@ -0,0 +1,15 @@ +package me.smartstore.exception; + +import me.smartstore.util.Message; + +public class InvalidSortTypeException extends RuntimeException { + + public InvalidSortTypeException() { + super(Message.ERR_MSG_INVALID_SORT_TYPE); + } + + public InvalidSortTypeException(String message) { + super(message); + } +} + diff --git a/ToyProject/src/me/smartstore/group/Group.java b/ToyProject/src/me/smartstore/group/Group.java new file mode 100644 index 00000000..bd09d519 --- /dev/null +++ b/ToyProject/src/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/ToyProject/src/me/smartstore/group/GroupType.java b/ToyProject/src/me/smartstore/group/GroupType.java new file mode 100644 index 00000000..34933e4f --- /dev/null +++ b/ToyProject/src/me/smartstore/group/GroupType.java @@ -0,0 +1,37 @@ +package me.smartstore.group; + +import me.smartstore.exception.InputRangeException; + +// 고객 분류 타입 +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; + if (this == G) return GENERAL; + if (this == V) return VIP; + if (this == VV) return VVIP; + return this; + } + + public static int getGroupTypeLevel(Group group) { + GroupType type = group.getGroupType(); + if (type==NONE) return 0; + else if (type==GENERAL) return 1; + else if (type==VIP) return 2; + else if (type==VVIP) return 3; + else return 0; + } + + public static GroupType[] getAllGroupTypes() { + return new GroupType[]{NONE, GENERAL, VIP, VVIP}; + } +} diff --git a/ToyProject/src/me/smartstore/group/Groups.java b/ToyProject/src/me/smartstore/group/Groups.java new file mode 100644 index 00000000..12a7c58d --- /dev/null +++ b/ToyProject/src/me/smartstore/group/Groups.java @@ -0,0 +1,91 @@ +package me.smartstore.group; + +import me.smartstore.arrays.DArray; + +import java.util.Arrays; +import java.util.Iterator; +import java.util.Objects; +import java.util.stream.IntStream; + +public class Groups extends DArray { + + private static Groups allGroups; + + public static Groups getInstance() { + if (allGroups == null) { + allGroups = new Groups(); + allGroups.add(new Group(new Parameter(), GroupType.NONE)); + } + return allGroups; + } + + private Groups() { + } + +// public Group find(GroupType groupType) { +// for (Object obj : allGroups.arrays) { +// Group group = (Group) obj; +// if (group.getGroupType() == groupType) return group; +// } +// return null; +// } + + public Group find(GroupType groupType) { + for (int i=0; i< allGroups.size(); i++) { + Group group = allGroups.get(i); + if (group.getGroupType()==groupType) { + return group; + } + } + return null; + } + +// public Group getGroupByParameter(int spentTime, int totalPay) { +// Group res = new Group(new Parameter(0, 0), GroupType.NONE); +// System.out.println("this : " + this); +// for (Group group : this) { +// System.out.println("Group test : " + group); +// if (spentTime >= group.getParameter().getMinTime() && totalPay >= group.getParameter().getMinPay()) { +// res = group; +// } +// } +// return res; +// } + +// public Group getGroupByParameter(int spentTime, int totalPay) { +// Group res = null; +// for (Group group : this) { +// if (spentTime >= group.getParameter().getMinTime() && +// totalPay >= group.getParameter().getMinPay()) { +// if (res == null || group.getParameter().getMinTime() > res.getParameter().getMinTime()) { +// res = group; +// } +// } +// } +// return res != null ? res : new Group(new Parameter(0, 0), GroupType.NONE); +// } + +// @Override +// public Iterator iterator() { +// return Arrays.stream(this.arrays).iterator(); +// } + +// @Override +// public Iterator iterator() { +// return IntStream.range(0, size) +// .mapToObj(i -> arrays[i]) +// .filter(Objects::nonNull) +// .map(obj -> (Group) obj) +// .iterator(); +// } + +// @Override +// public Iterator iterator() { +// return Arrays.stream(arrays) +// .filter(Objects::nonNull) +// .map(obj -> (Group) obj) +// .iterator(); +// } + + +} diff --git a/ToyProject/src/me/smartstore/group/Parameter.java b/ToyProject/src/me/smartstore/group/Parameter.java new file mode 100644 index 00000000..6d9d6d2c --- /dev/null +++ b/ToyProject/src/me/smartstore/group/Parameter.java @@ -0,0 +1,57 @@ +package me.smartstore.group; + +import java.util.Objects; + +/** + * 고객 분류기준 + * 등급 분류를 위해서 minTime, minPay 최소시간과 최소금액을 설정함 + */ +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/ToyProject/src/me/smartstore/menu/CustomerMenu.java b/ToyProject/src/me/smartstore/menu/CustomerMenu.java new file mode 100644 index 00000000..552db461 --- /dev/null +++ b/ToyProject/src/me/smartstore/menu/CustomerMenu.java @@ -0,0 +1,204 @@ +package me.smartstore.menu; + +import me.smartstore.customer.Customer; +import me.smartstore.customer.Customers; +import me.smartstore.exception.EmptyArrayException; +import me.smartstore.exception.InputEndException; +import me.smartstore.exception.InputRangeException; +import me.smartstore.util.Message; + + +public class CustomerMenu implements Menu { + + private static CustomerMenu customerMenu; + private final Customers allCustomers; + + private CustomerMenu() { + this.allCustomers = Customers.getInstance(); + } + + public static CustomerMenu getInstance() { + if (customerMenu == null) { + customerMenu = new CustomerMenu(); + } + return customerMenu; + } + + /** + * 고객 관리 담당 메서드 + * + */ + @Override + public void manage() { + while (true) { + int choice = chooseMenu(new String[]{ + "Add Customer Data", + "View Customer Data", + "Update Customer Data", + "Delete Customer Data", + "Back"}); + if (choice == 1) addCustomer(); + else if (choice == 2) viewCustomer(); + else if (choice == 3) updateCustomer(); + else if (choice == 4) deleteCustomer(); + else break; + } + } + + private void addCustomer() { + while (true) { + System.out.println("How many customers to input?"); + try { + Integer addCustomerNum = Integer.parseInt(nextLine(Message.END_MSG)); + if (addCustomerNum <= 0) { + throw new InputRangeException(); + } + for (int i=0; i " + allCustomers.get(i), (i+1)); + System.out.println(String.format("No. %d =>", (i + 1)) + allCustomers.get(i)); + } + } catch (EmptyArrayException e) { + System.out.println(Message.ERR_MSG_ARR_EMPTY); + } + } + + private void updateCustomer() { + while (true) { + viewCustomer(); + try { + System.out.printf(String.format("\nWhich customer do you want to update? (%d ~ %d)", 1, allCustomers.size())); + Integer choice = Integer.parseInt(nextLine(Message.END_MSG)); + if (choice < 1 || choice > allCustomers.size()) throw new InputRangeException(); + Customer customer = allCustomers.get(choice-1); + makeCustomerInfo(customer); + allCustomers.refresh(); + } catch (InputEndException e) { + System.out.println(Message.ERR_MSG_INPUT_END); + break; + } catch (InputRangeException e) { + System.out.println(Message.ERR_MSG_INVALID_INPUT_RANGE); + } + } + } + +// private void deleteCustomer() { +// while (true) { +// try { +// if (allCustomers.size() == 0) { +// throw new EmptyArrayException(); +// } +// for (int i = 0; i < allCustomers.size(); i++) { +// //System.out.println("No. %d => " + allCustomers.get(i), (i+1)); +// System.out.println(String.format("No. %d =>", (i + 1)) + allCustomers.get(i)); +// } +// //System.out.println("\nWhich customer (%d ~ %d)", 1, allCustomers.size()+1); +// System.out.println(String.format("\nWhich customer (%d ~ %d)", 1, allCustomers.size())); +// Integer choice = Integer.parseInt(nextLine()); +// } catch (EmptyArrayException e) { +// System.out.println(Message.ERR_MSG_ARR_EMPTY); +// } +// } +// } + + private void deleteCustomer() { + while (true) { + try { + viewCustomer(); + System.out.println(String.format("\nWhich customer do you want to delete? (%d ~ %d)", 1, allCustomers.size())); + Integer choice = Integer.parseInt(nextLine(Message.END_MSG)); + System.out.println(allCustomers.pop(choice-1)); + } catch (InputRangeException e) { + System.out.println(Message.ERR_MSG_INVALID_INPUT_RANGE); + break; + } + } + } + +// private void printCustomerList() { +// try { +// if (allCustomers.size() == 0) { +// throw new EmptyArrayException(); +// } +// System.out.println("\n======= Customer Info. ======="); +// for (int i = 0; i < allCustomers.size(); i++) { +// //System.out.println("No. %d => " + allCustomers.get(i), (i+1)); +// System.out.println(String.format("No. %d =>", (i + 1)) + allCustomers.get(i)); +// } +// } catch (Exception e) { +// +// } +// } +} diff --git a/ToyProject/src/me/smartstore/menu/GroupMenu.java b/ToyProject/src/me/smartstore/menu/GroupMenu.java new file mode 100644 index 00000000..47eb1ecd --- /dev/null +++ b/ToyProject/src/me/smartstore/menu/GroupMenu.java @@ -0,0 +1,216 @@ +package me.smartstore.menu; + +import me.smartstore.customer.Customers; +import me.smartstore.exception.InputEndException; +import me.smartstore.exception.InputRangeException; +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.InputMismatchException; + +public class GroupMenu implements Menu { + + private final Groups allGroups; + private final Customers allCustomers; + + private static GroupMenu groupMenu; + + public static GroupMenu getInstance() { + if (groupMenu == null) { + groupMenu = new GroupMenu(); + } + return groupMenu; + } + + private GroupMenu() { + this.allGroups = Groups.getInstance(); + this.allCustomers = Customers.getInstance(); + } + + /** + * 고객 등급별 파라미터를 설정하는 함수 + * 메인메뉴에서 Parameter를 입력했을 때 호출 + */ + @Override + public void manage() { + while (true) { + 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 break; // Back + } + } + + /** + * 설정하려는 등급에 해당하는 GroupType을 사용자가 입력하면, 그 등급을 GroupType으로 반환함. + * @return : 사용자가 선택한 GroupType + * + */ + public GroupType chooseGroup() { + while (true) { + try { + System.out.println("Which group (GENERAL (G), VIP (V), VVIP (VV))? "); + String choice = nextLine(Message.END_MSG); + GroupType groupType = GroupType.valueOf(choice).replaceFullName(); + return groupType; + } catch (InputEndException e) { + System.out.println("**"); + System.out.println(Message.ERR_MSG_INPUT_END); + break; + } catch (IllegalArgumentException e) { + System.out.println(Message.ERR_MSG_INVALID_INPUT_RANGE); + } + } + return null; + } + + /** + * setParameter() + * @return : void + * 최초 그룹 파라미터를 초기화 해주는 메서드 + */ + public void setParameter() { + while (true) { + try { + //GroupType groupType = chooseGroup(); + System.out.println("Which group (GENERAL (G), VIP (V), VVIP (VV))? "); + String choice = nextLine(Message.END_MSG); + GroupType groupType = GroupType.valueOf(choice).replaceFullName(); + + System.out.println("groupType : " + groupType); + Group group = allGroups.find(groupType); + System.out.println("group : " + group); + if (group != null && group.getParameter() != null) { + // 즉, 이미 초기화됨 + System.out.println("\n" + group.getGroupType() + " group already exists."); + } else { + // 파라미터가 초기화 되지 않음, 여기까지 오면 + Parameter parameter = new Parameter(); + makeParameter(parameter); + group = new Group(parameter, groupType); + allGroups.add(group); + allCustomers.refresh(); + //group.setParameter(parameter); + //allCustomers.refresh(); + } + if (groupType==null) { + System.out.println("null"); + throw new IllegalArgumentException(); + } + System.out.println(String.format("\nGroupType : %s", groupType.name())); + System.out.println("Parameter : " + group.getParameter()); + } catch (InputEndException e) { + System.out.println(Message.END_MSG); + break; + } catch (IllegalArgumentException e) { + System.out.println(Message.ERR_MSG_INVALID_INPUT_RANGE); + } catch (InputRangeException e) { + System.out.println(e.getMessage()); + } + } + } + + public void makeParameter(Parameter parameter) { + while (true) { + int choice = chooseMenu(new String[] { + "Minimum Spent Time", + "Minimum Total Pay", + "Back"}); + if (choice==1) { // minimum spent time setting + while (true) { + try { + System.out.println("\nInput Minimum Spent Time"); + Integer minTime = Integer.parseInt(nextLine()); // 재검토 + if (minTime<0) throw new InputRangeException(); + parameter.setMinTime(minTime); + break; + } catch (InputMismatchException e) { + System.out.println(Message.ERR_MSG_INVALID_INPUT_TYPE); + } catch (InputRangeException e) { + System.out.println(Message.ERR_MSG_INVALID_INPUT_RANGE); + } + } + } else if (choice==2) { // minimum total pay + while (true) { + try { + System.out.println("\nInput Minimum Total Pay"); + Integer minPay = Integer.parseInt(nextLine()); + if (minPay<0) throw new InputRangeException(); + parameter.setMinPay(minPay); + break; + } catch (InputMismatchException e) { + System.out.println(Message.ERR_MSG_INVALID_INPUT_TYPE); + } + } + } else { // back + break; + } + } + + } + + + /** + * 설정한 파라미터를 보여주는 메서드 + */ + public void viewParameter() { + while (true) { + try { + System.out.println("\nWhich group (GENERAL (G), VIP (V), VVIP (VV))?"); + String data = nextLine(Message.END_MSG); + GroupType groupType = GroupType.valueOf(data).replaceFullName(); + Group group = allGroups.find(groupType); + System.out.println("group test : " + group); + + System.out.println(String.format("\nGroupType : %s", groupType.name())); + System.out.println("Parameter : " + (group != null ? group.getParameter() : null)); + } catch (InputEndException e) { + System.out.println(Message.ERR_MSG_INPUT_END); + break; + } + } + } + + /** + * 설정한 파라미터를 업데이트 하는 메서드 + */ + public void updateParameter() { + while (true) { + try { + System.out.println("\nWhich group (GENERAL (G), VIP (V), VVIP (VV))?"); + String data = nextLine(Message.END_MSG); + GroupType groupType = GroupType.valueOf(data).replaceFullName(); + Group group = allGroups.find(groupType); + + if (group == null) { + System.out.println("No parameter. Set the parameter first."); + break; + } else { + Parameter parameter = group.getParameter(); + makeParameter(parameter); // parameter 클래스의 필드 내용 변경 + group.setParameter(parameter); // group 클래스의 parameter 필드 변경 + allCustomers.refresh(); +// Parameter parameter = new Parameter(); +// makeParameter(parameter); +// group = new Group(parameter, groupType); +// allGroups.add(group); +// allCustomers.refresh(); + } + + } catch (InputEndException e) { + System.out.println(Message.ERR_MSG_INPUT_END); + break; + } catch (IllegalArgumentException e) { + System.out.println(Message.ERR_MSG_INVALID_INPUT_RANGE); + } + } + } +} diff --git a/ToyProject/src/me/smartstore/menu/MainMenu.java b/ToyProject/src/me/smartstore/menu/MainMenu.java new file mode 100644 index 00000000..f211bed0 --- /dev/null +++ b/ToyProject/src/me/smartstore/menu/MainMenu.java @@ -0,0 +1,38 @@ +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(); + + private static MainMenu mainMenu; + + public static MainMenu getInstance() { + if (mainMenu == null) { + mainMenu = new MainMenu(); + } + return mainMenu; + } + + private MainMenu() { + } + + @Override + public void manage() { + while (true) { + int choice = mainMenu.chooseMenu(new String[] { + "Parameter", + "Customer Data", + "Classification Summary", + "Quit"}); + if (choice == 1) groupMenu.manage(); + else if (choice == 2) customerMenu.manage(); + else if (choice == 3) summaryMenu.manage(); + else { + System.out.println("Program Finished"); + break; + } + } + } +} diff --git a/ToyProject/src/me/smartstore/menu/Menu.java b/ToyProject/src/me/smartstore/menu/Menu.java new file mode 100644 index 00000000..7f0a1df4 --- /dev/null +++ b/ToyProject/src/me/smartstore/menu/Menu.java @@ -0,0 +1,59 @@ +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 sc = new Scanner(System.in); + + default String nextLine() { + return sc.nextLine().toUpperCase(); + } + + default String nextLine(String end) { + System.out.println("** Press 'end', if you want to exit! **"); + String str = sc.nextLine().toUpperCase(); + if (str.equals(end)) throw new InputEndException(); + return str; + } + + default int chooseMenu(String[] menus) { + while (true) { + try { + System.out.println("==============================="); + for (int i=0; i= 1 && choice <= menus.length) return choice; + throw new InputRangeException(); + } catch (InputMismatchException e) { + System.out.println(Message.ERR_MSG_INVALID_INPUT_FORMAT); + } catch (InputRangeException e) { + System.out.println(Message.ERR_MSG_INVALID_INPUT_RANGE); + } catch (NumberFormatException e) { + System.out.println(Message.ERR_MSG_INVALID_INPUT_TYPE); + } + } + } + + default int parsingInt(String data) { + try { + return Integer.parseInt(data); + } catch (NumberFormatException e) { + throw new InputMismatchException(Message.ERR_MSG_INVALID_INPUT_FORMAT); + } + } + + /** + * void manage() 각 서브메뉴 관리 함수 + * 각 서브메뉴의 최상위 메뉴 + */ + void manage(); +} diff --git a/ToyProject/src/me/smartstore/menu/SummaryMenu.java b/ToyProject/src/me/smartstore/menu/SummaryMenu.java new file mode 100644 index 00000000..e49a2b86 --- /dev/null +++ b/ToyProject/src/me/smartstore/menu/SummaryMenu.java @@ -0,0 +1,135 @@ +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.exception.InvalidSortTypeException; +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 me.smartstore.util.SortType; + +import static me.smartstore.util.SortType.*; + +import java.util.Arrays; +import java.util.Comparator; +import java.util.List; +import java.util.Map; + +public class SummaryMenu implements Menu { + + private static SummaryMenu summaryMenu; + private final Groups allGroups; + private final Customers allCustomers; + + private static final int ASCENDING = 1; + private static final int DESCENDING = -1; + private static final int END = 100; + + private SummaryMenu() { + this.allGroups = Groups.getInstance(); + this.allCustomers = Customers.getInstance(); + } + + public static SummaryMenu getInstance() { + if (summaryMenu == null) { + summaryMenu = new SummaryMenu(); + } + return summaryMenu; + } + + /** + * 요약 사항 관리 메서드 + */ + @Override + public void manage() { + while (true) { + int choice = chooseMenu(new String[] { + "Summary", + "Summary (Sorted By Name)", + "Summary (Sorted By Time)", + "Summary (Sorted By Pay)", + "Back"}); + if (choice == 1) getSummary(allCustomers.getAllCustomers()); + else if (choice == 2) getSortedSummary(CUSTOMER_NAME); + else if (choice == 3) getSortedSummary(CUSTOMER_TIME); + else if (choice == 4) getSortedSummary(CUSTOMER_PAYMENT); + else break; + } + } + + private void getSortedSummary(SortType type) { + while (true) { + int classificationValue = getClassificationValue(); + try { + getSummary(allCustomers.getSortedCustomers(type.getCustomerComparator(classificationValue))); + } catch (InvalidSortTypeException e) { + System.out.println(Message.ERR_MSG_INVALID_INPUT_TYPE); + return; + } + } + } + + private int getClassificationValue() { + while (true) { + try { + System.out.println("Which order ASCENDING(A) or DESCENDING(D)?"); + String str = nextLine(Message.END_MSG); + + if (!str.equals("A") && !str.equals("D")) throw new InputRangeException(); + + if (str.equals("A")) return ASCENDING; + else return DESCENDING; + } catch (InputEndException e) { + System.out.println(Message.ERR_MSG_INPUT_END); + break; + } catch (InputRangeException e) { + System.out.println(Message.ERR_MSG_INVALID_INPUT_RANGE); + } + } + return END; + } + + private void getSummary(Customer[] customers) { + GroupType[] types = GroupType.getAllGroupTypes(); + for (GroupType type : types) { + printSummary(customers, type); + } + } + + private void printSummary(Customer[] customers, GroupType groupType) { +// System.out.println("=============================="); +// System.out.printf("Group : %s ( Time : %s, Pay : %s )\n", group.getGroupType(), group.getParameter().getMinTime(), group.getParameter().getMinPay()); +// System.out.println("=============================="); + + Group group = null; + Parameter parameter = null; + + for (int i=0; i< allGroups.size(); i++) { + if (allGroups.get(i).getGroupType() == groupType) { + group = allGroups.get(i); + parameter = group.getParameter(); + } +// System.out.println("=============================="); +// System.out.printf("Group : %s ( Time : %s, Pay : %s )\n", groupType.name(), parameter.getMinTime(), parameter.getMinPay()); + } + + System.out.println("=============================="); + System.out.printf("Group : %s ( Time : %s, Pay : %s )\n", groupType.name(), parameter.getMinTime(), parameter.getMinPay()); + + if (group != null) { + for (int i=0; i", (i + 1)) + allCustomers.get(i)); + } + } + } + else if (group == null) { + System.out.println("Null"); + } + } +} diff --git a/ToyProject/src/me/smartstore/util/Message.java b/ToyProject/src/me/smartstore/util/Message.java new file mode 100644 index 00000000..f75ecb74 --- /dev/null +++ b/ToyProject/src/me/smartstore/util/Message.java @@ -0,0 +1,12 @@ +package me.smartstore.util; + +public interface Message { + String ERR_MSG_INPUT_END = "END is pressed. Exit this menu."; + String ERR_MSG_INVALID_INPUT_RANGE = "Invalid Input. Please try again."; + String ERR_MSG_INVALID_INPUT_FORMAT = "Invalid Format for Input. Please try again."; + String ERR_MSG_INVALID_INPUT_TYPE = "Invalid Type for Input. Please try again."; + String END_MSG = "END"; + String ERR_MSG_ARR_EMPTY = "There's no customer in this application. Please inset customer info firstly."; + String ERR_MSG_ARR_OUT_OF_BOUNDARY = "This array's size exceeds the capacity of the array."; + String ERR_MSG_INVALID_SORT_TYPE = "The sort type that has been initiated is not valid."; +} diff --git a/ToyProject/src/me/smartstore/util/SortType.java b/ToyProject/src/me/smartstore/util/SortType.java new file mode 100644 index 00000000..ad5ad40e --- /dev/null +++ b/ToyProject/src/me/smartstore/util/SortType.java @@ -0,0 +1,23 @@ +package me.smartstore.util; + +import me.smartstore.customer.Customer; +import me.smartstore.exception.InvalidSortTypeException; + +import java.util.Comparator; + +public enum SortType { + CUSTOMER_NAME, CUSTOMER_TIME, CUSTOMER_PAYMENT; + + public Comparator getCustomerComparator(int classificationValue) { + if (this == CUSTOMER_NAME) { + return (customer1, customer2) -> classificationValue * customer1.getCustomerName().compareTo(customer2.getCustomerName()); + } + else if (this == CUSTOMER_TIME) { + return (customer1, customer2) -> classificationValue * customer1.getCustomerTotalTime().compareTo(customer2.getCustomerTotalTime()); + } + else if (this == CUSTOMER_PAYMENT) { + return (customer1, customer2) -> classificationValue * customer1.getCustomerTotalPay().compareTo(customer2.getCustomerTotalPay()); + } + throw new InvalidSortTypeException(); + } +}