객체지향적인 계산기를 만드는것에 도전하였다. 이를 바탕으로 if-else문과 enum에 대해서 공부하고 객체지향적인 계산기를 만들어보자.
다음의 코드를 보자
public class Caculator {
public static long calculate(char operator, long value1, long value2) {
switch(operator):
if (operator == '+') {
return vaule1 + value2;
} else if (operator == '-') {
return value1 - value2;
} else if (operator == '*') {
return value1 * value2;
} else if (operator == '/') {
return value1 / value2;
} else {
System.out.println("잘못된 연산자 입력!");
return 0;
}
}
매개변수로 들어온 operation에 따라 다른 연산을 해주는 계산기이다. if문은 기본적으로 if를 만날때마다 조건문을 만족하는지 인트럭션이 필요하다. 그렇다면 operation이 어떠한 값으로 들어왔는지 한번에 알 수 있는 방법은 없을까??
다음의 코드를 보자.
public class Caculator {
public static long calculate(String operator, long value1, long value2) {
switch (operator) {
case '+':
return value1 + value2;
break;
case '-':
return value1 - value2;
break;
case '*':
return value1 * value2;
break;
case '/':
return value1 / value2;
break;
default:
System.out.println("잘못된 연산자 입력!");
return 0;
break;
}
}
}
switch문인 경우에는 처음에 입력값을 확인하는 인터럭션만 존재하고 조건을 확인할 때에는 점프테이블을 통해 한번에 이동한다. 따라서 if else 문보다는 더 효율적이라고 생각할 수 있다.
하지만 calculate 메소드를 보면 더하기, 빼기, 곱하기, 나누기의 연산을 수핼할 뿐만 아니라 operation이 어떻게 들어왔는지 구분해주는 역할까지 수행한다. 이는 SOLID의 원칙중 SRP에 어긋난다고 생각이 든다.
그렇다면 우리는 if문을 쓰지 않고 어떻게 이를 최대한 객체지향적으로 만들 수 있을까??
map과 다형성을 이용해 하는 방법과, enum 클래스를 이용한 방법이 떠오른다. 각각 코드를 통해 살펴보자.
public class CalculatorMapper {
private final static Map<Character, Calculator> calculatorMap = new HashMap<>();
static {
calculatorMap.put('+', new PlusCalculate());
calculatorMap.put('-', new MinusCalculator());
calculatorMap.put('/', new DivideCalculator());
calculatorMap.put('*', new MultipleCalculator());
}
public static Calculator getCalculator(char operator) {
return calculatorMap.get(operator);
}
}
위와 같은 방식으로 분기문을 사용하지 않고 연산별 계산기를 지정해 줄 수 있다.
다음으로 Enum을 사용하기에 앞서 enum의 개념을 잡고 가보도록 하자.
Enum
Enum이라는 것은 Enumeration의 앞글자로 열거형이라는 뜻을 가지고 있으며 서로 연관되거나 또는 관련이 있는 상수들의 집합을 의미한다.
자바에서의 Enum의 특징
- 자바에서의 Enum은 클래스이다.
- 상수 하나당 자신의 인스턴스를 하나씩 만들어 public static final 필드로 공개한다.
- 따라서 클라이언트가 인스턴스를 직접 생성하거나 확장할 수 없어. 열거형으로 만들어진 인스턴스들은 딱 하나씩만 존재한다.
Enum의 특징에 대해서 알았다. 특징만으로는 Enum을 활용하기에는 어려울 것이다. 다음의 코드를 보며 Enum을 활용하는 법을 익혀보도록 하자.
public enum CalculatorType {
PLUS((value1, value2) -> value1 + value2),
MINUS((value1, value2) -> value1 - value2),
MULTIPLY((value1, value2) -> value1 * value2),
DIVIDE((value1, value2) -> value1 / value2);
private BiFunction<Long, Long, Long> expression;
CalculatorType(BiFunction<Long, Long, Long> expression) { this.expression = expression;}
public long calculate(long value1, long value2) { return expression.apply(value1, value2);}
}
코드를 간단히 설명하자면, CalculatorType이라는 Enum 클래스 내에 PLUS, MINUS, MULTIPLY, DIVIDE의 상수가 public static final 필드로 생성되며 생성과 동시에 각 인스턴스별 BinFunction이 PLUS, MINUS...에 따라 다르게 초기화가 된다.
이렇든 Enum 클래스의 두번째 특징인 public static fianl 필드로 공개한다 라는 점을 명심하며 이를 활용해 코드를 작성할 방법을 생각할 수 있다.
'Java' 카테고리의 다른 글
자바의 Collection (0) | 2023.01.20 |
---|---|
자바의 변수와 타입 (0) | 2023.01.19 |
JVM & GC (2) | 2022.11.29 |
객체지향 프로그래밍 (2) | 2022.11.10 |