24.07.30

윤지현·2024년 7월 30일

TIL

목록 보기
27/75

Level2의 개인과제 9~10을 풀었다.

  • 9번 ArithmeticCalculator 클래스의 연산 메서드에 책임(역할)이 많아 보입니다. 사칙연산 각각의 기능을 담당하는 AddOperator, SubtractOperator, MultiplyOperator, DivideOperator 클래스를 만들어 연산 메서드의 책임을 분리 해봅니다. (SRP)
  • SRP란?
➡ SOLID 원칙 중 하나로, 클래스나 모듈이 오직 하나의 책임만 가져야 한다는 원칙

그래서 ArithmeticCalculator 연산을 4개로 나누었다.

public class AddOperator {
    public double operate(int num1, int num2) {
        return num1 + num2;
    }
}
public class DivideOperator{
    public double operate(int num1, int num2) throws BadException{
        if (num2 == 0) {
            throw new BadException("분모가 0이 아닌 양의 정수");
        } else {
            return num1 / num2;
        }
    }
}
public class MultiplyOperator {
    public double operate(int num1, int num2) {
        return num1 * num2;
    }
}
package calculator;

public class MultiplyOperator {
    public double operate(int num1, int num2) {
        return num1 * num2;
    }
}

그 다음 ArithmeticCalculator 클래스도 수정했다.

public class ArithmeticCalculator extends Calculator {
    // 필드
    private static ArrayList<Double> arithmeticList;
    private int num1;           // 첫 번째 정수
    private int num2;           // 두 번째 정수
    private char operator;      // 연산자

    private final AddOperator add = new AddOperator();
    private final SubtractOperator sub = new SubtractOperator();
    private final MultiplyOperator multi = new MultiplyOperator();
    private final DivideOperator div = new DivideOperator();

    // 생성자
    public ArithmeticCalculator() {
        this.arithmeticList = new ArrayList<>();
@@ -28,20 +33,16 @@ public double calculate() throws BadException {
        double result = 0;
        switch (this.operator) {
            case '+':
                result = this.num1 + this.num2;
                result = add.operate(num1, num2);
                break;
            case '-':
                result = this.num1 - this.num2;
                result = sub.operate(num1, num2);
                break;
            case '*':
                result = this.num1 * this.num2;
                result = multi.operate(num1, num2);
                break;
            case '/':
                if (this.num2 == 0) {
                    throw new BadException("분모가 0이 아닌 양의 정수");
                } else {
                    result = this.num1 / this.num2;
                }
                result = div.operate(num1, num2);
                break;
            default:
                throw new BadException("사칙연산자[+, -, *, /]");
        }
        return result;
    }
}

기존에 작성했던 코드 실행 결과 그대로 잘 나온다.

  • 10번 ArithmeticCalculator 클래스에 추가로 나머지 연산(%) 기능을 추가하기 위해 ModOperator 클래스를 만들어 추가합니다.

여기서 Operator이라는 interface를 이용하였다.(잘되었는지 모르겠다....)

// 각 사칙연산에 대하여 계산하는 클래스와 Calculator 클래스를 연결 해주는 interface 선언
public interface Operator {
    // 각 사칙연산의 인터페이스 추상 메서드 오버라이딩
    public int operate(int num1, int num2);
}

그 다음 나머지 연산(%)하는 ModOperator 클래스 생성 및 다른 사칙연산 클래스도 변경

public class ModOperator implements Operator{
    @Override
    public int operate(int num1, int num2) {
        return num1 % num2;
    }
}

Calculator 클래스에서 interface인 Operator로 Calculator와 ArithmeticCalculator 클래스를 연결하기 위해 Calculator 코드 수정

public abstract class Calculator {

    // Calculator 클래스에서 사칙연산 클래스 활용(interface를 이용)
    protected Operator addOperator = new AddOperator();             // 더하기
    protected Operator subOperator = new SubtractOperator();        // 빼기
    protected Operator multiOperator = new MultiplyOperator();      // 곱하기
    protected Operator divOperator = new DivideOperator();          // 나누기(몫)
    protected Operator modOperator = new ModOperator();             // 나누기(나머지)

    public int add(int num1, int num2) {
        return addOperator.operate(num1, num2);
    }

    public int sub(int num1, int num2) {
        return subOperator.operate(num1, num2);
    }

    public int multi(int num1, int num2) {
        return multiOperator.operate(num1, num2);
    }

    public int div(int num1, int num2) throws BadException{
        if (num2 == 0) {
            throw new BadException("\"분모가 0이 아닌 양의 정수\"");
        } else
            return divOperator.operate(num1, num2);
    }

    public int mod(int num1, int num2) throws BadException{
        if (num2 == 0) {
            throw new BadException("\"분모가 0이 아닌 양의 정수\"");
        } else
            return modOperator.operate(num1, num2);
    }
}

또한 ArithmeticCalculator 클래스도 수정

public class ArithmeticCalculator extends Calculator {
    // 필드
    private static ArrayList<Double> arithmeticList;
    private int num1;           // 첫 번째 정수
    private int num2;           // 두 번째 정수
    private char operator;      // 연산자

    private final AddOperator add = new AddOperator();
    private final SubtractOperator sub = new SubtractOperator();
    private final MultiplyOperator multi = new MultiplyOperator();
    private final DivideOperator div = new DivideOperator();

    // 생성자
    public ArithmeticCalculator() {
        this.arithmeticList = new ArrayList<>();
@@ -30,19 +25,22 @@ public void setArithmetic(int num1, int num2, char op) {
    // 사칙연산 메서드
    @Override
    public double calculate() throws BadException {
        double result = 0;
        int result = 0;
        switch (this.operator) {
            case '+':
                result = add.operate(num1, num2);
                result = add(num1, num2);
                break;
            case '-':
                result = sub.operate(num1, num2);
                result = sub(num1, num2);
                break;
            case '*':
                result = multi.operate(num1, num2);
                result = multi(num1, num2);
                break;
            case '/':
                result = div.operate(num1, num2);
                result = div(num1, num2);
                break;
            case '%':
                result = mod(num1, num2);
                break;
            default:
                throw new BadException("사칙연산자[+, -, *, /]");
        }
        return result;
    }
}

다행히 잘 실행이 된다.

  • 후기
    하면서 순간 정지된 적이 여러 번 생겼다가 gpt한테 물어보고 해서 해결했다. level3도 도전을 해봐야 겠다.
profile
첫 시작

0개의 댓글