- 코드 중복 삭제
- 자료형 변경
- Lambda & Enum 활용하기
기존 코드에서 Setter를 설정하기 위해 CalculatorClass에서
private double result=0;으로 result값을 설정해줬었다.
하지만 이는 코드의 중복을 만들고 있었다.
public class CalculatorClass {
private ArrayList<Double> calculateList = new ArrayList<>(); //연산 결과 저장하기
private double result=0;
public void setResult(double result){ //setter 설정하기
this.result = result; //코드 중복
calculateList.add(result);
}
int add(int a, int b){ //더하기
int result = a+b;
return result;
}
때문에 private result 선언을 지우고
public class CalculatorClass {
private ArrayList<Double> calculateList = new ArrayList<>(); //연산 결과 저장하기
public void setResult(double result){//setter 설정하기
calculateList.add(result);
}
int add(int a, int b){ //더하기
return a+b;
}
바로 return값에 저장할 수 있도록 설정했다.
지금 내가 짠 코드를 활용하서 계산기 결과를 출력하면 int 타입의 값으로 나와도 꼭 뒤에 소수점이 붙어 출력되는 문제점이 있었다.
소수점이 붙으면 double로, 아니면 int로 저장될 수 있도록 설정해보자!
📌 Object란?
자바에서 모든 클래스의 부모(최상위 클래스)!
→ 모든 데이터 타입(int, double, String, ArrayList 등)을 저장할 수 있는 자료형
Object는 어떤 타입이든 저장할 수 있기 때문에 int든 double이든 다 저장할 수 있다~!
CalculateClass를 고쳐보자.
(1) 변수 타입을 Object로 변경
private ArrayList<Object> calculateList = new ArrayList<>(); //연산 결과 저장하기
//setter 설정하기
public void setResult(Object result){
calculateList.add(result);
}
(2) 나누기는 double int 두가지 타입이 다 나올 수 있으니 경우의 수를 나누어 처리
Object divide(int a, int b) {
if (b==0){
throw new ArithmeticException("0으로는 나눌 수 없습니다");
}
if (a % b == 0) { // 나머지가 없으면 int 반환
return a / b;
} else { // 나머지가 있으면 double 반환
return (double) a / b;
}
}
(3) main 클래스에서 result 변수 타입도 변경해주자
//결과값 변수 설정하기
Object result = 0;
이렇게하면 저장되는 변수의 타입을 하나로 통일하지 않고도 저장 가능하다!
기존 CalculatorClass2에서는 사칙연산 (+, -, *, /)을 개별 메서드로 구현하고, 연산 결과를 ArrayList<Object>에 저장하는 구조
CalculatorClass2 파일에 모든 메서드가 다 들어있으니 가독성이 떨어지고 복잡해보였음OperatorType 클래스): OperatorType Enum파일을 만들어서 연산자를 정의, Lambda 표현식
→ 연산 로직을 직접 연결
public enum OperatorType {
Plus("+", (a, b) -> a + b),
Minus("-", (a, b) -> a - b),
Multiply("*", (a, b) -> a * b),
Divide("/", (a, b) -> {
if (b == 0) { //예외처리
throw new ArithmeticException("0으로는 나눌 수 없습니다");
}
return a / b;
});
private final String operator;
private final BiFunction<Integer, Integer, Object> operation;
final을 붙여서 상수취급 받을 수 있도록 변호나private : 객체 외부에서 직접 접근하지 못하게 함apply(), findOperator() 메서드로만 접근 가능하도록 // 연산 수행 메서드
public Object apply(int a, int b) {
return operation.apply(a, b);
}
// Enum에서 입력받은 연산자에 맞는 연산 찾아서 계산하기
public static OperatorType findOperator(String operator) {
for (OperatorType value : OperatorType.values()) {
if (value.operator.equals(operator)) {
return value;
}
}
throw new IllegalArgumentException("잘못 입력하셨습니다: " + operator);
}
나머지 메서드(리스트(ArrayList), 연산 기록 저장(setter)&반환(getter)&지우기(remove))들을 ArithmeticCalculator 클래스를 만들어서 따로 관리!
💊 캡슐화 성공~~!
파일 구조가 이렇게 바뀌게 된다!
📦 JavaCalculator
┣ 📂out
┣ 📂src
┃ ┣ 📂 MakeCalculator3
┃ ┃ ┣ ArithmeticCalculator.java //나머지 메서드 저장 클래스
┃ ┃ ┣ CalculatorMain3.java //메인클래스
┃ ┃ ┗ OperatorType.java //연산자 저장된 enum
┃ ┃
┗ 📜 README.md
OperatorType에 연산자와 연산 로직을 함께 정의하여 가독성↑ + 유지보수 쉬움.findOperator() 메서드를 통해 입력된 연산자를 자동으로 찾는다제네릭 설명 글
🔗 https://velog.io/@minjee2758/Generic-%EC%A0%9C%EB%84%A4%EB%A6%AD
나는 Generic을 다루는 것이 매우 서툴기 때문에 기존 코드를 보호하기 위해 브랜치 만들어 나눠서 작업했다. branch MakeGeneric🪵