#18 oop : calculator

This commit is contained in:
haerong22
2022-08-29 03:14:48 +09:00
parent 7677bd5280
commit 57eb21d6a9
10 changed files with 207 additions and 0 deletions

View File

@@ -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);
}
}

View File

@@ -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("올바른 연산자가 아닙니다."));
}
}

View File

@@ -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();
}
}

View File

@@ -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();
}
}

View File

@@ -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();
}
}

View File

@@ -0,0 +1,7 @@
package org.example.calculator.operator;
public interface NewArithmeticOperator {
boolean supports(String operator);
int calculator(PositiveNumber operand1, PositiveNumber operand2);
}

View File

@@ -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;
}
}

View File

@@ -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();
}
}

View File

@@ -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)
);
}
}

View File

@@ -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또는 음수를 전달 할 수 없습니다.");
}
}