숙제 : 계산기 만들기
Step 1
더하기, 빼기, 나누기, 곱하기 연산을 수행할 수 있는 Calculator 클래스를 만듭니다.
- Calulator 클래스는 연산을 수행하는 반환 타입이 double인 calculate 메서드를 가지고 있습니다.
- calculate 메서드는 String 타입의 operator 매개변수를 통해 연산자 매개값을 받습니다.
- int 타입의 firstNumber, secondNumber 매개변수를 통해 피연산자 값을 받습니다.
- calculate 메서드는 전달받은 피연산자, 연산자를 사용하여 연산을 수행합니다.

Step 2
나머지 연산자(%)를 수행할 수 있게 Calculator 클래스 내부 코드를 변경합니다
Step 3
AddOperation(더하기), SubstractOperation(빼기), MultiplyOperation(곱하기), DivideOperation(나누기) 연산 클래스를 만든 후 클래스 간의 관계를 고려하여 Calculator 클래스와 관계를 맺습니다.
- 관계를 맺은 후 필요하다면 Calculator 클래스의 내부 코드를 변경합니다.
- 나머지 연산자(%) 기능은 제외합니다.
- Step 2 와 비교하여 어떠한 점이 개선되었는지 스스로 생각해 봅니다.
- hint. 클래스의 책임(단일 책임 원칙)

Step 4
AddOperation(더하기), SubstractOperation(빼기), MultiplyOperation(곱하기), DivideOperation(나누기) 연산 클래스들을 AbstractOperation(추상 클래스)를 사용하여 추상화하고 Calculator 클래스의 내부 코드를 변경합니다.
- Step 3 와 비교해서 어떠한 점이 개선되었는지 스스로 생각해 봅니다.
- hint. 클래스 간의 결합도, 의존성(의존성 역전 원칙)
- Calculator의 calculate 메서드의 매개변수가 변경되었습니다.

Step 1,2
Calulator
public class Calulator {
public double calculate(String operate,int fristnumber, int secondnumber) {
int result=0;
if (operate.equals("+")){
result= fristnumber + secondnumber;
} else if (operate.equals("-")){
result= fristnumber - secondnumber;
}else if (operate.equals("*")){
result= fristnumber * secondnumber;
}else if (operate.equals("/")){
result= fristnumber / secondnumber;
}else if (operate.equals("%")){
result= fristnumber % secondnumber;
}
return result;
}
}
main
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
int fristnumber;
int secondnumber;
String operate;
Scanner input = new Scanner(System.in);
System.out.print("첫번째 숫자를 입력 하세요: ");
fristnumber = input.nextInt();
System.out.print("두번째 숫자를 입력 하세요: ");
secondnumber = input.nextInt();
System.out.print("연산자를 입력 하세요 ");
operate = input.next();
Calulator cal = new Calulator();
System.out.print("계산 결과는 : " + cal.calculate(operate,fristnumber,secondnumber) );
}
}

Step 3
//Calulator
public class Calulator {
AddOperation addOperation;
SubstractOperation substractOperation;
MultiplyOperation multiplyOperation;
DivideOperation divideOperation;
Calulator(AddOperation addOperation) {
this.addOperation = addOperation;
} //생성자 선언시 덧셈 클래스도 같이 생성
Calulator(SubstractOperation substractOperation) {
this.substractOperation = substractOperation;
}//생성자 선언시 뺄셈 클래스도 같이 생성
Calulator(MultiplyOperation multiplyOperation) {
this.multiplyOperation = multiplyOperation;
}//생성자 선언시 곱셈 클래스도 같이 생성
Calulator(DivideOperation divideOperation) {
this.divideOperation = divideOperation;
}//생성자 선언시 나눗셈 클래스도 같이 생성
public double calculate(String operate, int fristnumber, int secondnumber) {
double result = 0;
if (operate.equals("+")) {
result = addOperation.AddOperation(fristnumber, secondnumber);
} else if (operate.equals("-")) {
result = substractOperation.SubstractOperation(fristnumber, secondnumber);
} else if (operate.equals("*")) {
result = multiplyOperation.MultiplyOperation(fristnumber, secondnumber);
} else if (operate.equals("/")) {
result = divideOperation.DivideOperation(fristnumber, secondnumber);
}
return result;
}
}
//AddOperation
public class AddOperation {
public double AddOperation (int fristnumber, int secondnumber) {
return fristnumber + secondnumber;
}
}
//SubstractOperation
public class SubstractOperation {
public double SubstractOperation (int fristnumber, int secondnumber) {
return fristnumber - secondnumber;
}
}
//MultiplyOperation
public class MultiplyOperation {
public double MultiplyOperation (int fristnumber, int secondnumber) {
return fristnumber * secondnumber;
}
}
//DivideOperation
public class DivideOperation {
public double DivideOperation (int fristnumber, int secondnumber) {
return fristnumber / secondnumber;
}
}
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
int fristnumber;
int secondnumber;
String operate;
while (true) {
Scanner input = new Scanner(System.in);
System.out.print("첫번째 숫자를 입력 하세요: ");
fristnumber = input.nextInt();
System.out.print("두번째 숫자를 입력 하세요: ");
secondnumber = input.nextInt();
System.out.print("연산자를 입력 하세요 ");
operate = input.next();
if (operate.equals("+")) {
Calulator cal = new Calulator(new AddOperation());
System.out.println(cal.calculate(operate, fristnumber, secondnumber));
} else if (operate.equals("-")) {
Calulator cal = new Calulator(new SubstractOperation());
System.out.println(cal.calculate(operate, fristnumber, secondnumber)
);
} else if (operate.equals("*")) {
Calulator cal = new Calulator(new MultiplyOperation());
System.out.println(cal.calculate(operate, fristnumber, secondnumber)
);
} else if (operate.equals("/")) {
Calulator cal = new Calulator(new DivideOperation());
System.out.println(cal.calculate(operate, fristnumber, secondnumber)
);
}
}
}
}

Step 4
//Calulator
public class Calulator {
AbstractOperation operation;
public Calulator (AbstractOperation operation) {
this.operation = operation;
}
public void setOperation(AbstractOperation operation) {
this.operation = operation;
}
public double calculate(int fristnumber, int secondnumber) {
double result = 0;
result = operation.operate(fristnumber,secondnumber);
return result;
}
}
//AbstractOperation
public abstract class AbstractOperation {
abstract double operate(int firstNumber, int secondNumber);
}
//AddOperation
public class AddOperation extends AbstractOperation {
@Override
double operate (int fristnumber, int secondnumber) {
return fristnumber + secondnumber;
}
}
//SubstractOperation
public class SubstractOperation extends AbstractOperation {
@Override
double operate (int fristnumber, int secondnumber) {
return fristnumber - secondnumber;
}
}
//MultiplyOperation
public class MultiplyOperation extends AbstractOperation {
@Override
double operate (int fristnumber, int secondnumber) {
return fristnumber * secondnumber;
}
}
//DivideOperation
public class DivideOperation extends AbstractOperation {
@Override
double operate (int fristnumber, int secondnumber) {
return fristnumber / secondnumber;
}
}
//Main
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
int fristnumber;
int secondnumber;
String operate;
while (true) {
Scanner input = new Scanner(System.in);
System.out.print("첫번째 숫자를 입력 하세요: ");
fristnumber = input.nextInt();
System.out.print("두번째 숫자를 입력 하세요: ");
secondnumber = input.nextInt();
System.out.print("연산자를 입력 하세요 ");
operate = input.next();
if (operate.equals("+")) {
Calulator cal = new Calulator(new AddOperation());
System.out.println(cal.calculate(fristnumber, secondnumber));
} else if (operate.equals("-")) {
Calulator cal = new Calulator(new SubstractOperation());
System.out.println(cal.calculate(fristnumber, secondnumber));
} else if (operate.equals("*")) {
Calulator cal = new Calulator(new MultiplyOperation());
System.out.println(cal.calculate(fristnumber, secondnumber));
} else if (operate.equals("/")) {
Calulator cal = new Calulator(new DivideOperation());
System.out.println(cal.calculate(fristnumber, secondnumber));
}
}
}
}

해당 과제를 진행 하면서 어려웠던점.
처음숙제 내용은 상속후 진행하면 쉽겠다고 생각하여 extend를 진행 후 진행 했었다.
과제 완료 후 정답을 확인 해보니 전혀 다른 코드가 나와.. 이상하다고 생각 하고 다시 공부를 해봤다.
Step 3에 단일 책임원칙에 대한 내용을 찾아보기 시작했고
단일 책임 원칙이란 객체는 단하나의 책임을 가져야 한다의 정의 이다.
이런 정의가 왜 필요한가 하면 한 클래스 내에 여러가지의 기능을 가진 다양한 매서드가 존재 하는데 하나의 매서드를 수정 진행 하면 다른 기능의 매서드들의 영향이 갈수 있다고 한다.
이렇게 생각의 정리를 하니 extend 사용 방식은 맞지 않고 단일 책임 원칙을 지키면서 하는 방식을 찾아보니 상속 말고 합성이 있는걸 알게 되었다. 해당 내용을 찾아보니 말그대로 클래스 내에 다른 클래스에 객체를 선언 후 코드를 짜는 형식으로 확인이된다.
해당 문제를 해결하니 자연스럽게 Step 4도 자연스럽게 해결 되었다.