일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- 내일배움캠프
- 스파르타내일배움캠프TIL
- Inventory
- 문자열
- Firebase
- c#
- UnrealEngine
- 유클리드호제법
- BFS
- QueryDSL
- Unity
- 해시
- 프로그래머스
- 이분탐색
- 알고리즘
- Unity2D
- Photon
- 스파르타내일배움캠프
- C++
- 구현
- 유니티
- unityui
- UE4
- 순열
- 워크플로
- FSM
- 언리얼엔진
- 스택
- Unity3d
- 포톤
- Today
- Total
개발 낙서장
[TIL] 내일배움캠프 7일차 - 계산기 만들기 - 본문
오늘의 학습 키워드📚
Step1
- 더하기, 빼기, 곱하기, 나누기 기능이 있는 Calculator 클래스 만들기
- double을 반환하고 String, int, int를 파라미터로 받는 calculate 메소드 구현
Calculator 클래스
package calculator;
public class Calculator {
public double Calculate(String op, int num1, int num2) {
double result = 0;
switch(op) {
case "+":
result = num1 + num2;
break;
case "-":
result = num1 - num2;
break;
case "*":
result = num1 * num2;
break;
case "/":
result = (double)num1 / (double)num2;
break;
}
return result;
}
}
Main 클래스(Step4 까지 Main은 동일)
import calculator.Calculator;
public class Main {
public static void main(String[] args) {
Calculator cal = new Calculator();
System.out.println("Add : 1 + 2 = " + cal.Calculate("+", 1, 2));
System.out.println("Substract : 1 - 2 = " + cal.Calculate("-", 1, 2));
System.out.println("Multiply : 1 * 2 = " + cal.Calculate("*", 1, 2));
System.out.println("Divide : 1 / 2 = " + cal.Calculate("/", 1, 2));
}
}
Step2
- 나머지 기능 추가
package calculator;
public class Calculator {
public double Calculate(String op, int num1, int num2) {
double result = 0;
switch(op) {
case "+":
result = num1 + num2;
break;
case "-":
result = num1 - num2;
break;
case "*":
result = num1 * num2;
break;
case "/":
result = (double)num1 / (double)num2;
break;
case "%":
result = num1 % num2;
break;
default:
result = 0;
break;
}
return result;
}
}
Step3
- 각 기능(더하기, 빼기, 곱하기, 나누기)들을 클래스로 나누어 구현
더하기 클래스(빼기, 곱하기, 나누기 클래스 전부 구조는 동일)
package calculator;
public class AddOperation {
public double Operate(int num1, int num2) {
double result = 0;
result = num1 + num2;
return result;
}
}
Calculator 클래스
package calculator;
public class Calculator {
AddOperation add = new AddOperation();
SubstractOperation sub = new SubstractOperation();
MultiplyOperation mul = new MultiplyOperation();
DivideOperation div = new DivideOperation();
public double Calculate(String op, int num1, int num2) {
double result = 0;
switch(op) {
case "+":
result = add.Operate(num1, num2);
break;
case "-":
result = sub.Operate(num1, num2);
break;
case "*":
result = mul.Operate(num1, num2);
break;
case "/":
result = div.Operate(num1, num2);
break;
case "%":
result = num1 % num2;
break;
default:
result = 0;
break;
}
return result;
}
}
각 클래스를 기능 별로 나눠놓으니 유지보수도 편해지고 클래스 구조가 직관적이 됐다.
물론 이런 간단한 작업에 대해서는 이런 식으로 클래스를 굳이 나눌 필요가 없다고 생각할 수 있지만
기능들을 추가하다 보면 코드가 얼마나 길어질지 쉽게 예측하기 어렵기 때문에 아무리 간단한 작업이라도 설계 단계부터 객체지향 설계를 하는 것이 좋다고 생각한다.
Step4
- 각 클래스들을 추상화하여 상속한다.
AbstractOperation 추상 클래스
상속하는 클래스 들이 기능을 구현할 수 있도록 Operate라는 추상 메소드를 선언
package calculator;
public abstract class AbstractOperation {
public abstract double Operate(int num1, int num2);
}
AddOperation 클래스(다른 기능 클래스 또한 같은 구조를 갖고 있다.)
상속받은 클래스 마다 구조는 같지만 기능을 다르게 구현했다는 것을 표현하기 위해 출력문을 추가했다.
package calculator;
public class AddOperation extends AbstractOperation{
@Override
public double Operate(int num1, int num2) {
double result = 0;
result = num1 + num2;
System.out.print("Add : " + num1 + " + " + num2);
return result;
}
}
Calculator 클래스
계산기 클래스답게 계산만 해서 값을 반환하는 역할
(Alt + Insert : 생성자나 Getter, Setter 등을 간편하게 생성하는 단축키)
package calculator;
public class Calculator {
AbstractOperation operation;
public Calculator(AbstractOperation operation) {
this.operation = operation;
}
public void setOperation(AbstractOperation operation) {
this.operation = operation;
}
public double Calculate(int num1, int num2) {
double result = 0;
result = operation.Operate(num1, num2);
return result;
}
}
Main 클래스
반환받은 값을 출력해준다.
import calculator.*;
public class Main {
public static void main(String[] args) {
Calculator cal = new Calculator(new AddOperation());
System.out.println(" = " + cal.Calculate(1, 2));
cal.setOperation(new SubtractOperation());
System.out.println(" = " + cal.Calculate(1, 2));
cal.setOperation(new MultiplyOperation());
System.out.println(" = " + cal.Calculate(1, 2));
cal.setOperation(new DivideOperation());
System.out.println(" = " + cal.Calculate(1, 2));
}
}
사실 대충 보면 구조는 그냥 클래스를 나눴을 때와 매우 비슷하다.
각 클래스 별로 Operate 함수를 구현하고 이를 Calculator 클래스에서 계산값을 반환하여 Main 클래스에서 값을 출력하는 구조는 같다.
다만 위에서 말했듯 기능들이 추가될수록 구조적이지 않은 클래스는 코드 양이 기하급수적으로 늘어나기 때문에 이렇게 객체지향적인 설계는 반드시 필요하다.
또한 추상 클래스와 추상 메소드를 만들어 상속받으면 나중에 새로운 메소드나 기능들을 추가, 수정, 삭제할 때 훨씬 편리하게 할 수 있다.
여기서도 나눠져 있던 클래스들을 추상 클래스로 만들어 상속받는 형태로 바꾸니 Calculator 클래스 내부에서도 간편하게 작업을 처리할 수 있게 됐고 Main 클래스에서도 연산자를 String으로 받는 것이 아니라 setOperation을 통해 유동적으로 바꿀 수 있게 됐다.
오늘의 회고💬
객체 지향 설계는 약간 새해 다짐 같은 느낌이다.
시작할 땐 이것저것 야무지게 계획하지만 막상 코딩하고 구현하면서 점점 대충 되는대로 코딩하거나 아예 객체 지양을 하는 경우가 생기는 것 같다.
결국 나중에 수정하게 될 때 땅을 치고 후회하고...😥
객체 지향에 대한 공부는 끝이 없다고 생각한다. 코드가 길어질수록 복잡해질수록 기능이 많아질수록 객체 지향의 중요도는 더더욱 올라가는데 그만큼 객체 지향 개발의 난이도도 높아지기 때문에 계속해서 연구하고 공부해야 하는 것이라 생각한다.
내일의 계획📜
내일은 정말 자바 강의를 완강할 수 있도록 해야겠다!
'Java > Sparta' 카테고리의 다른 글
JAVA 개인 과제 - 키오스크 만들기 - 1일차 (0) | 2024.01.05 |
---|---|
[TIL] 내일배움캠프 8일차 - 예외 처리 - (0) | 2024.01.04 |
[TIL] 내일배움캠프 6일차 - 자료구조 - (0) | 2024.01.02 |
[TIL] 내일배움캠프 5일차 - 모듈 - (0) | 2023.12.28 |
[TIL] 내일배움캠프 4일차 - Java로 코딩하기 - (0) | 2023.12.27 |