#18 oop : calculator
This commit is contained in:
@@ -0,0 +1,48 @@
|
||||
package org.example.calculator;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
public enum ArithmeticOperator {
|
||||
|
||||
ADDITION("+") {
|
||||
@Override
|
||||
public int arithmeticCalculate(int operand1, int operand2) {
|
||||
return operand1 + operand2;
|
||||
}
|
||||
},
|
||||
SUBTRACTION("-") {
|
||||
@Override
|
||||
public int arithmeticCalculate(int operand1, int operand2) {
|
||||
return operand1 - operand2;
|
||||
}
|
||||
},
|
||||
MULTIPLICATION("*") {
|
||||
@Override
|
||||
public int arithmeticCalculate(int operand1, int operand2) {
|
||||
return operand1 * operand2;
|
||||
}
|
||||
},
|
||||
DIVISION("/") {
|
||||
@Override
|
||||
public int arithmeticCalculate(int operand1, int operand2) {
|
||||
return operand1 / operand2;
|
||||
}
|
||||
};
|
||||
|
||||
private final String operator;
|
||||
|
||||
ArithmeticOperator(String operator) {
|
||||
this.operator = operator;
|
||||
}
|
||||
|
||||
|
||||
public abstract int arithmeticCalculate(final int operand1, final int operand2);
|
||||
|
||||
public static int calculate(int o1, String operator, int o2) {
|
||||
return Arrays.stream(values())
|
||||
.filter(v -> v.operator.equals(operator))
|
||||
.findFirst()
|
||||
.orElseThrow(() -> new IllegalArgumentException("올바른 연산이 아닙니다."))
|
||||
.arithmeticCalculate(o1, o2);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package org.example.calculator;
|
||||
|
||||
import org.example.calculator.operator.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class Calculator {
|
||||
|
||||
private static final List<NewArithmeticOperator> arithmeticOperators =
|
||||
List.of(new AdditionOperator(), new SubtractionOperator(), new MultiplicationOperator(), new DivisionOperator());
|
||||
public static int calculate(PositiveNumber o1, String operator, PositiveNumber o2) {
|
||||
return arithmeticOperators.stream()
|
||||
.filter(arithmeticOperators -> arithmeticOperators.supports(operator))
|
||||
.map(arithmeticOperators -> arithmeticOperators.calculator(o1, o2))
|
||||
.findFirst()
|
||||
.orElseThrow(() -> new IllegalArgumentException("올바른 연산자가 아닙니다."));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package org.example.calculator.operator;
|
||||
|
||||
public class AdditionOperator implements NewArithmeticOperator {
|
||||
@Override
|
||||
public boolean supports(String operator) {
|
||||
return "+".equals(operator);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int calculator(PositiveNumber operand1, PositiveNumber operand2) {
|
||||
return operand1.toInt() + operand2.toInt();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package org.example.calculator.operator;
|
||||
|
||||
public class DivisionOperator implements NewArithmeticOperator {
|
||||
@Override
|
||||
public boolean supports(String operator) {
|
||||
return "/".equals(operator);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int calculator(PositiveNumber operand1, PositiveNumber operand2) {
|
||||
return operand1.toInt() / operand2.toInt();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package org.example.calculator.operator;
|
||||
|
||||
public class MultiplicationOperator implements NewArithmeticOperator {
|
||||
@Override
|
||||
public boolean supports(String operator) {
|
||||
return "*".equals(operator);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int calculator(PositiveNumber operand1, PositiveNumber operand2) {
|
||||
return operand1.toInt() * operand2.toInt();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package org.example.calculator.operator;
|
||||
|
||||
public interface NewArithmeticOperator {
|
||||
|
||||
boolean supports(String operator);
|
||||
int calculator(PositiveNumber operand1, PositiveNumber operand2);
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package org.example.calculator.operator;
|
||||
|
||||
public class PositiveNumber {
|
||||
private final int value;
|
||||
|
||||
public PositiveNumber(int value) {
|
||||
validate(value);
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
private void validate(int value) {
|
||||
if (isNegativeNumber(value)) {
|
||||
throw new IllegalArgumentException("0또는 음수를 전달 할 수 없습니다.");
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isNegativeNumber(int value) {
|
||||
return value <= 0;
|
||||
}
|
||||
|
||||
public int toInt() {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package org.example.calculator.operator;
|
||||
|
||||
public class SubtractionOperator implements NewArithmeticOperator {
|
||||
@Override
|
||||
public boolean supports(String operator) {
|
||||
return "-".equals(operator);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int calculator(PositiveNumber operand1, PositiveNumber operand2) {
|
||||
return operand1.toInt() - operand2.toInt();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
package org.example.calculator;
|
||||
|
||||
import org.example.calculator.operator.PositiveNumber;
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.Arguments;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.junit.jupiter.params.provider.Arguments.arguments;
|
||||
|
||||
/**
|
||||
* 양수로만 계산 가능
|
||||
* 나눗셈에서 0을 나누는 경우 IllegalArgumentException 발생
|
||||
* MVC 패턴 기반으로 구현
|
||||
*/
|
||||
public class CalculatorTest {
|
||||
|
||||
@DisplayName("덧셈 연산을 수행한다.")
|
||||
@ParameterizedTest
|
||||
@MethodSource("formulaAndResult")
|
||||
void calculateTest(int operand1, String operator, int operand2, int result) {
|
||||
|
||||
int calculateResult =
|
||||
Calculator.calculate(new PositiveNumber(operand1), operator, new PositiveNumber(operand2));
|
||||
|
||||
assertThat(calculateResult).isEqualTo(result);
|
||||
}
|
||||
|
||||
private static Stream<Arguments> formulaAndResult() {
|
||||
return Stream.of(
|
||||
arguments(1, "+", 2, 3),
|
||||
arguments(1, "-", 2, -1),
|
||||
arguments(4, "*", 2, 8),
|
||||
arguments(4, "/", 2, 2)
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package org.example.calculator.operator;
|
||||
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.ValueSource;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThatCode;
|
||||
|
||||
class PositiveNumberTest {
|
||||
|
||||
@ParameterizedTest
|
||||
@ValueSource(ints = {0, -1})
|
||||
void createTest(int value) {
|
||||
assertThatCode(() -> new PositiveNumber(value))
|
||||
.isInstanceOf(IllegalArgumentException.class)
|
||||
.hasMessage("0또는 음수를 전달 할 수 없습니다.");
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user