1.
2.
3.
/* 사칙연산 계산 부분 메소드 매개변수로 요소를 받아 계산 후 리턴
throws 키워드를 통해 직접 예외를 처리하지않고 발생지에서 처리요청
열거 객체를 통한 사칙연산 구분 */
/* CalculatorManager 가 가지는 구현객체를 통해 객체를 추상클래스타입 변수로 갈아끼워 호출명은 동일하지만
* 계산연산이 바뀌도록 다형성 부여 */
public double calculate(T firstNum, T secondNum, String operator) throws ArithmeticException {
operatorType = OperatorType.find(operator);
switch (operatorType) {
case ADD:
cm.setCalculate(new AddCalculator());
break;
case SUB:
cm.setCalculate(new SubCalculator());
break;
case MULT:
cm.setCalculate(new MultCalculator());
break;
case DIV:
cm.setCalculate(new DivCalculator());
break;
case REM:
cm.setCalculate(new RemCalculator());
break;
}
// 연산 과정 및 결과 저장 메서드 호출.
result = cm.getCalculate().calculate(firstNum, secondNum);
saveCalculationProcess(firstNum, secondNum, result, operator);
return result;
}
/* 사칙연산 계산 부분 메소드 매개변수로 요소를 받아 계산 후 리턴
throws 키워드를 통해 직접 예외를 처리하지않고 발생지에서 처리요청*/
// AbstractCalculator 객체를 받음으로써 calculate()는 오퍼레이터를 몰라도 연산이 가능
public double calculate(T firstNum, T secondNum, AbstractCalculator cm) throws ArithmeticException {
// 연산 과정 및 결과 저장 메서드 호출.
result = cm.calculate(firstNum, secondNum);
saveCalculationProcess(firstNum, secondNum, result, cm.getOperator());
return result;
}
switch (OperatorType.find(operator)) {
case ADD:
cm.setCalculate(new AddCalculator());
break;
case SUB:
cm.setCalculate(new SubCalculator());
break;
case MULT:
cm.setCalculate(new MultCalculator());
break;
case DIV:
cm.setCalculate(new DivCalculator());
break;
case REM:
cm.setCalculate(new RemCalculator());
break;
}
/* Calculator 객체를 통한 calculate() 메소드를 통해 계산.
정수인지 실수인지에 대한 타입분간.
입력값중 음수가 있는지 판단.*/
if (fisrtdoublecnt != 0 && seconddoublecnt != 0) {
if (calc.negativeIntegerChecker(firstNumDouble, secondNumDouble)) {
System.out.println("양수만 입력해주세요.");
}
System.out.println(firstNumDouble + " " + operator + " " + secondNumDouble + " = " + calc.calculate(firstNumDouble, secondNumDouble, cm.getCalculate()));
public enum Operator {
PLUS("+", (num1, num2) -> num1 + num2),
MINUS("-", (num1, num2) -> num1 - num2),
MULTIPLY("*", (num1, num2) -> num1 * num2),
DIVIDE("/", (num1, num2) -> num1 / num2);
or
public enum Operator {
PLUS("+") {
@Override
public int calculate(int num1, int num2) {
return num1 + num2;
}
},
// 빈 List 요청 확인 메소드
private boolean emptyListChecker() {
return firstNumbers.isEmpty();
}
// 요청 index 가 size 를 넘지 않았는지 체크메소드
private boolean listIndexChecker(int index) {
return firstNumbers.size() < index;
}
//입력값 중 음수가 있는지 확인하는 메소드
public boolean negativeIntegerChecker(T firstNum, T secondNum) {
return firstNum.doubleValue() < 0 || secondNum.doubleValue() < 0;
}
// 빈 List 요청 확인 메소드
private boolean isEmptyList() {
return firstNumbers.isEmpty();
}
// 요청 index 가 size 를 넘지 않았는지 체크메소드
private boolean isIndexOutOfBounds(int index) {
return firstNumbers.size() < index;
}
//입력값 중 음수가 있는지 확인하는 메소드
public boolean isNegativeNumber(T firstNum, T secondNum) {
return firstNum.doubleValue() < 0 || secondNum.doubleValue() < 0;
}
명사로 짓는다. 테스트클래스는 클래스명이 TEST로 끝난다.동사로 짓는다.

작은 프로젝트이기에 구분이 힘들지않지만 큰프로젝트일수록 패키지의 구조, 특히 Spring의 경우 패키지구조에 영향을 크게받기에 습관화가 필요할거같다.