main 함수 코드
package com.example.mycalcurator
import java.lang.NumberFormatException
//Lv3 : AddOperation(더하기), SubstractOperation(빼기), MultiplyOperation(곱하기), DivideOperation(나누기) 연산 클래스를 만든 후 클래스간의 관계를 고려하여 Calculator 클래스와 관계를 맺기
// 입력값 안정성 높이기 -> 완료
fun main() {
var num1: Double
var num2: Double
var op: Int
var keepOrExit: Int
println("-------------------계산기-------------------")
println("--------연산할 첫 번째 숫자를 입력하세요--------")
num1 = isNumber()
println("-------연산자에 해당하는 숫자를 입력하세요-------")
println("-----1(더하기) 2(빼기) 3(곱하기) 4(나누기)-----")
op = isValidOperator()
println("--------연산할 두 번째 숫자를 입력하세요--------")
num2 = isNumber()
val cal = Calculator()
var result = cal.calculator(num1, num2, op)
println("-----------연산 결과 : ${result} -----------")
while (true) {
println("-이어서 연산 하시려면 1 종료하시려면 2 입력해주세요-")
while (true) {
try {
keepOrExit = readLine()!!.toInt()
if (keepOrExit == 1) break
else if (keepOrExit == 2) {
println("---------------계산기 종료----------------")
return
}
else println("입력값 오류! 이어서 연산하려면 1 종료하려면 2를 입력해주세요")
} catch (e: NumberFormatException) {
println("입력값 오류! 숫자를 입력해주세요. 1 -> 계속 2 -> 종료")
}
}
println("-------연산자에 해당하는 숫자를 입력하세요-------")
println("-----1(더하기) 2(빼기) 3(곱하기) 4(나누기)-----")
op = isValidOperator()
println("--------연산할 두 번째 숫자를 입력하세요--------")
num2 = isNumber()
result = cal.calculator(result, num2, op)
println("--------------연산 결과 : ${result} --------------")
}
}
fun isNumber() : Double{
while (true) {
try {
var num = readLine()!!.toDouble()
return num
} catch (e: NumberFormatException) {
println("입력값 오류! 숫자를 입력해주세요.")
}
}
}
fun isValidOperator() : Int {
while (true) {
try {
var op = readLine()!!.toInt()
if (op in 1..4) return op
else println("1부터 4까지 연산자에 해당하는 숫자를 입력하세요")
} catch (e: NumberFormatException) {
println("입력값 오류! 숫자를 입력해주세요.")
}
}
}
Calculator 클래스 코드
package com.example.mycalcurator
class Calculator {
fun calculator(num1: Double, num2: Double, op: Int): Double {
var result:Double = 0.0
val addOperation = AddOperation()
val substractOperation = SubstractOperation()
val multiflyOperation = MultiflyOperation()
val divideOperation = DivideOperation()
when (op) {
1 -> {result = addOperation.operation(num1,num2)}
2 -> {result = substractOperation.operation(num1,num2)}
3 -> {result = multiflyOperation.operation(num1,num2)}
4 -> {result = divideOperation.operation(num1,num2)}
}
return result
}
}
AddOperation 클래스, SubstractOperation 클래스 , MultiflyOperation 클래스 , DivideOperation 클래스
class AddOperation {
fun operation(num1:Double, num2:Double) :Double = (num1 + num2)
}
class SubstractOperation {
fun operation(num1:Double, num2:Double) :Double = (num1 - num2)
}
class MultiflyOperation {
fun operation(num1:Double, num2:Double) :Double = (num1 * num2)
}
class DivideOperation {
fun operation(num1:Double, num2:Double) :Double = (num1 / num2)
}
우선, 입력값 오류에 대한 안정성을 while문, try-catch문을 통해서 높였다. 그대로 적어놓으니 너무 지저분하여 2번 이상 쓰인 부분은 isNumber(), isValidOperator() 함수로 빼내어 코드량을 많이 줄였다.
단일 책임 원칙 (SRP : Single Responsibility Principle)에 따라 Calculator 클래스에서 각 연산자 클래스로 나누어 하나의 클래스가 하나의 기능만 책임질 수 있게 해주었다. 이로서 Calculator 클래스는 연산할 클래스들을 인스턴스화하여 op 값에 맞는 연산을 각 클래스들에게 맡기고 결과값을 리턴해주는 책임만 가지게 된다.