๐Ÿ•ฎ [Kotlin] ์ฝ”ํ‹€๋ฆฐ์œผ๋กœ ๊ณ„์‚ฐ๊ธฐ ๋‹จ๊ณ„๋ณ„ ๊ตฌํ˜„ํ•˜๊ธฐ
๋ฐ˜์‘ํ˜•

 

 


 

1. ๊ฐ„๋‹จํ•œ ์‚ฌ์น™์—ฐ์‚ฐ ๊ตฌํ˜„

 

package com.limheejin.calculator

class Calculator {

    fun main() {

        println("=============๊ณ„์‚ฐ๊ธฐ=============")
        println("์•ˆ๋…•ํ•˜์„ธ์š”! ์‚ฌ์น™์—ฐ์‚ฐ ๊ณ„์‚ฐ๊ธฐ์ž…๋‹ˆ๋‹ค.")
        println("๊ณ„์‚ฐ์„ ์›ํ•˜์‹œ๋Š” ์ •์ˆ˜ ๋‘ ๊ฐœ๋ฅผ ์ž…๋ ฅํ•ด์ฃผ์„ธ์š”. ")
        var num1 = Integer.parseInt(readLine())
        var num2 = Integer.parseInt(readLine())

        println("์›ํ•˜์‹œ๋Š” ์—ฐ์‚ฐ์ž ๊ธฐํ˜ธ๋ฅผ ์ž…๋ ฅํ•ด์ฃผ์„ธ์š” (+, -, *, / )")
        val operator = readLine()
        val result =
            when (operator) {
                "+" -> num1 + num2
                "-" -> num1 - num2
                "*" -> num1 * num2
                "/" -> num1 / num2
                else -> throw Exception("์ž˜๋ชป๋œ ์—ฐ์‚ฐ์ž์ž…๋‹ˆ๋‹ค. ๊ณ„์‚ฐ๊ธฐ๋ฅผ ๋‹ค์‹œ ์ผœ์ฃผ์„ธ์š”.")
            }

        println("${num1} ${operator} ${num2} = ${result} ์ž…๋‹ˆ๋‹ค.")
        println("๋‹ค์‹œ ์ง„ํ–‰ํ•˜์‹œ๊ฒ ์Šต๋‹ˆ๊นŒ? ๋„ค: 1 / ์•„๋‹ˆ์˜ค, ๋๋‚ด๊ฒ ์Šต๋‹ˆ๋‹ค: -1 ")

        var isExit = readLine()!!.toInt()
        when (isExit){
            1 -> main()
            -1 -> println("๊ณ„์‚ฐ์„ ์ข…๋ฃŒํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. ์ด์šฉํ•ด์ฃผ์…”์„œ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค.")
            else -> throw Exception("์ž˜๋ชป๋œ ์—ฐ์‚ฐ์ž์ž…๋‹ˆ๋‹ค. ๊ณ„์‚ฐ๊ธฐ๋ฅผ ๋‹ค์‹œ ์ผœ์ฃผ์„ธ์š”.")
        }



    }
}
  • ๋‹จ์ผ ํด๋ž˜์Šค ๋‚ด์—์„œ main ๋ฉ”์†Œ๋“œ๋งŒ์„ ์ด์šฉํ•ด ๊ตฌํ˜„ํ•œ ๊ฐ„๋‹จํ•œ ์ฝ”๋“œ๋‹ค.
  • ๊ฐ„๋‹จํ•œ ์‚ฌ์น™์—ฐ์‚ฐ, 1์„ ์ž…๋ ฅํ•  ์‹œ ๊ณ„์‚ฐ ๋ฐ˜๋ณต, -1์„ ์ž…๋ ฅํ•  ์‹œ ์ข…๋ฃŒ๋ฉ”์‹œ์ง€ ์ถœ๋ ฅ ์ •๋„์˜ ๊ธฐ๋Šฅ์ด ์žˆ๋‹ค.
  • ์ž˜๋ชป๋œ ์ˆซ์ž๋ฅผ ์ž…๋ ฅํ–ˆ์„ ๋•Œ์˜ ์˜ˆ์™ธ์ฒ˜๋ฆฌ๋„ ์—†๊ณ , ์ •์ˆ˜๊ฐ€ ์•„๋‹Œ ์‹ค์ˆ˜ ๊ณ„์‚ฐ๋„ ๋ชปํ•œ๋‹ค.
  • throw Exception์—์„œ Try catch Finally ์ฒ˜๋ฆฌ๋„ ์—†๋‹ค.

 

๋”๋ณด๊ธฐ

์‹ค์ œ ๊ตฌํ˜„

 

Main.kt

fun main() {
		val calculator = Calculator()
		
		while(true) { //while์˜ ํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ true๋กœ ๋‘ฌ์„œ ๋ฌดํ•œ ๋ฃจํ”„
				val select = readLine()!!.toInt()
				println("[1]๋ง์…ˆ, [2]๋บ„์…ˆ, [3]๊ณฑ์…ˆ, [4]๋‚˜๋ˆ—์…ˆ, [5]๋‚˜๋จธ์ง€, [-1]์ข…๋ฃŒ")
				
				val num1 = readLine()!!.toInt()
				println("์ฒซ ๋ฒˆ์งธ ์ˆซ์ž ์ž…๋ ฅ")
				val num2 = readLine()!!.toInt()
				println("๋‘ ๋ฒˆ์งธ ์ˆซ์ž ์ž…๋ ฅ")
				
				if(select == 1) {
						calculator.addOperation(num1, num2)
				} else if(select == 2) {
						calculator.minusOperation(num2, num1)
				} else if(select == 3) {
						calculator.multipleOperation(num1, num2)
				} else if(select == 4) {
						calculator.divideOperation(num2, num1)
				} else if(select == 5) {
						calculator.restOperation(num2, num1)
				} else {
						break
				}
		}
		println("์ข…๋ฃŒ")
}

 

Calculator.kt

class Calculator {
		fun addOperation(num1: Int, num2: Int) {
				val result = num1 + num2
				println("๊ฒฐ๊ณผ๊ฐ’์€: ${result}์ž…๋‹ˆ๋‹ค. ")
		}
		
		fun minusOperation(num1: Int, num2: Int) {
				val result = num2 - num1
				println("๊ฒฐ๊ณผ๊ฐ’์€: ${result}์ž…๋‹ˆ๋‹ค. ")
		}
		
		fun multipleOperation(num1: Int, num2: Int) {
				val result = num1 * num2
				println("๊ฒฐ๊ณผ๊ฐ’์€: ${result}์ž…๋‹ˆ๋‹ค. ")
		}
		
		fun divideOperation(num1: Int, num2: Int) {
				val result = num2 / num1
				println("๊ฒฐ๊ณผ๊ฐ’์€: ${result}์ž…๋‹ˆ๋‹ค. ")
		}
		
		fun restOperation(num1: Int, num2: Int) {
				val result = num2 % num1
				println("๊ฒฐ๊ณผ๊ฐ’์€: ${result}์ž…๋‹ˆ๋‹ค. ")
		}
}

 


 

 

 

2. ํด๋ž˜์Šค์˜ ๋ถ„๋ฆฌ์™€ ๋‹จ์ผ ์ฑ…์ž„ ์›์น™

 

Main.kt

fun main() {
		val addCalc = AddOperation()
		val minusCalc = SubstractOperation()
		val multipleCalc = MultiplyOperation()
		val divideCalc = DivideOperation()
		
		addCalc.addOperation(10, 20)
		minusCalc.minusOperation(20, 10)
		multipleCalc.multiplyOperation(10, 20)
		divideCalc.divideOperation(20, 10)
}
Calculator.kt

open class Calculator {
	 open fun operate(num1: Int, num2: Int)
}
AddOperation.kt

class AddOperation: Calculator() {

		override fun operate(num1: Int, num2: Int) {
				val result = num1 + num2
				println("๊ฒฐ๊ณผ๊ฐ’์€: ${result}์ž…๋‹ˆ๋‹ค. ")
		}
}
SubstractOperation.kt

class SubstractOperation: Calculator() {

		override fun operate(num1: Int, num2: Int) {
				val result = num2 - num2
				println("๊ฒฐ๊ณผ๊ฐ’์€: ${result}์ž…๋‹ˆ๋‹ค. ")
		}
}
MultiplyOperation.kt

class MultiplyOperation: Calculator() {

		override fun operate(num1: Int, num2: Int) {
				val result = num1 * num2
				println("๊ฒฐ๊ณผ๊ฐ’์€: ${result}์ž…๋‹ˆ๋‹ค. ")
		}
}
DivideOperation.kt

class DivideOperation: Calculator() {

		override fun operate(num1: Int, num2: Int) {
				val result = num2 / num1
				println("๊ฒฐ๊ณผ๊ฐ’์€: ${result}์ž…๋‹ˆ๋‹ค. ")
		}
}

 

  • ๊ฐ ๊ธฐ๋Šฅ์— ๋งž๊ฒŒ ํด๋ž˜์Šค๋ฅผ ๋ถ„๋ฆฌํ•˜๊ณ , Calculator ํด๋ž˜์Šค๋„ ๋„ฃ์–ด์ค€๋‹ค.
  • ๋ชจ๋“  ํด๋ž˜์Šค๊ฐ€ 2๊ฐœ์˜ ๊ฐ’์„ ์ž…๋ ฅ ๋ฐ›๋Š”๋‹ค๋Š” ๊ฒƒ์€ ๊ณตํ†ต์ ์ด๋ฏ€๋กœ, Calculator ํด๋ž˜์Šค์—์„œ๋Š” ๋‘ ๊ฐœ์˜ ๊ฐ’์„ ๋ฐ›๋Š” ๋ฉ”์†Œ๋“œ๋ฅผ ๋งŒ๋“ ๋‹ค. ๋˜ํ•œ ์ƒ์†์„ ํ• ์ˆ˜ ์žˆ๊ฒŒ ํด๋ž˜์Šค์™€ ํ•จ์ˆ˜์— open ํ‚ค์›Œ๋“œ๋ฅผ ๋„ฃ์–ด์ค€๋‹ค.
  • ๊ฐ๊ฐ์˜ ์‚ฌ์น™์—ฐ์‚ฐ ํด๋ž˜์Šค์—์„œ Calculator ํด๋ž˜์Šค๋ฅผ ์ƒ์†๋ฐ›๊ณ  operate ํ•จ์ˆ˜๋ฅผ ์˜ค๋ฒ„๋ผ์ด๋”ฉํ•œ๋‹ค.
  • ๊ฐ์ฒด์ง€ํ–ฅ 5์›์น™(SOLID) ์ค‘ SRP๋Š” ํ•˜๋‚˜์˜ ๊ฐ์ฒด๋Š” ๋ฐ˜๋“œ์‹œ ํ•˜๋‚˜์˜ ๋™์ž‘๋งŒ์˜ ์ฑ…์ž„์„ ๊ฐ–๋Š”๋‹ค๋Š” ์›์น™์ด๋‹ค. 
  • ๊ฐ์ฒด๊ฐ€ ๋‹ด๋‹นํ•˜๋Š” ๋™์ž‘(์ฑ…์ž„)์ด ๋งŽ์•„์งˆ์ˆ˜๋ก ํ•ด๋‹น ๊ฐ์ฒด์˜ ๋ณ€๊ฒฝ์— ๋”ฐ๋ฅธ ์˜ํ–ฅ๋„์˜ ์–‘๊ณผ ๋ฒ”์œ„๊ฐ€ ๋งค์šฐ ์ปค์ง„๋‹ค. ๋‹จ์ผ ์ฑ…์ž„ ์›์น™์€ ํŠน์ • ๊ฐ์ฒด์˜ ์ฑ…์ž„ ์˜์กด์„ฑ ๊ณผ์ค‘์„ ์ตœ๋Œ€ํ•œ ์ง€์–‘ํ•˜๊ธฐ ์œ„ํ•œ ์›์น™์ด๋‹ค.

 

 


 

3. ์ถ”์ƒํ™”, ํด๋ž˜์Šค ๊ฐ„์˜ ๊ฒฐํ•ฉ๋„, ์˜์กด์„ฑ(์˜์กด์„ฑ ์—ญ์ „ ์›์น™)

 

Main.kt

fun main() {
    val addCalc = Calculator(AddOperation())
    println("10๋”ํ•˜๊ธฐ 20 ๊ฒฐ๊ณผ๋Š” : ${addCalc.operate(10, 20)} ์ž…๋‹ˆ๋‹ค")

    val minusCalc = Calculator(SubstractOperation())
    println("20๋นผ๊ธฐ 10 ๊ฒฐ๊ณผ๋Š” : ${minusCalc.operate(20, 10)} ์ž…๋‹ˆ๋‹ค")

    val multipleCalc = Calculator(MultiplyOperation())
    println("10๊ณฑํ•˜๊ธฐ 20 ๊ฒฐ๊ณผ๋Š” : ${multipleCalc.operate(10, 20)} ์ž…๋‹ˆ๋‹ค")

    val divideCalc = Calculator(DivideOperation())
    println("20๋‚˜๋ˆ„๊ธฐ 10 ๊ฒฐ๊ณผ๋Š” : ${divideCalc.operate(20, 10)} ์ž…๋‹ˆ๋‹ค")
}
Calculator.kt

class Calculator(private val operator: AbstractOperation) {
    fun operate(num1: Int, num2: Int): Double {
        return operator.operate(num1, num2)
    }
}
AbstractOperation.kt

abstract class AbstractOperation {
    abstract fun operate(num1: Int, num2: Int): Double
}
AddOperation.kt

class AddOperation: AbstractOperation() {
    override fun operate(num1: Int, num2: Int): Double = (num1 + num2).toDouble()
}
SubstractOperation.kt

class SubstractOperation: AbstractOperation() {
    override fun operate(num1: Int, num2: Int): Double = (num1 - num2).toDouble()
}
MultiplyOperation.kt

class MultiplyOperation: AbstractOperation() {
    override fun operate(num1: Int, num2: Int): Double = (num1 * num2).toDouble()
}
DivideOperation.kt

class DivideOperation: AbstractOperation() {
    override fun operate(num1: Int, num2: Int): Double {
        require(num2 != 0) {
            ArithmeticException("Divide by Zero")
        }
        return (num1 / num2).toDouble()
    }
}
  • open class: ์ผ๋ฐ˜์ ์ธ ํด๋ž˜์Šค, ๋‹จ๋…์œผ๋กœ ๊ฐ์ฒด๊ฐ€ ๋˜์–ด ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Œ
    abstract class: ์ถ”์ƒ ํด๋ž˜์Šค, ๊ฐ์ฒด๋ฅผ ์ง์ ‘ ์ƒ์„ฑํ•  ์ˆ˜ ์—†์Œ. ๊ตฌํ˜„ ์—†์ด ์„ ์–ธ๋งŒ ๋˜์–ด ์žˆ์–ด, ์ƒ์† ๋ฐ ์žฌ์ •์˜๋งŒ ๊ฐ€๋Šฅ
  • ๊ฐ์ฒด์ง€ํ–ฅ 5์›์น™(SOLID) ์ค‘ DIP๋Š” "์ถ”์ƒํ™”์— ์˜์กดํ•ด์•ผ์ง€, ๊ตฌ์ฒดํ™”์— ์˜์กดํ•˜๋ฉด ์•ˆ ๋œ๋‹ค" ๋Š” ์›์น™์ด๋‹ค.
  • ์ž์‹ ๋ณด๋‹ค ๋ณ€ํ™”ํ•˜๊ธฐ ์‰ฌ์šด ๊ฒƒ์„ ์˜์กดํ•ด์„œ๋Š” ์•ˆ ๋˜๊ณ , ๊ฑฐ์˜ ๋ณ€ํ™”๊ฐ€ ์—†๋Š” ๊ฐœ๋…์— ์˜์กดํ•ด์•ผ ํ•œ๋‹ค
  • ์ถ”์ƒํ™”๋ฅผ ์œ„ํ•ด AbstractOperation์ด๋ผ๋Š” ์ถ”์ƒํด๋ž˜์Šค ์ƒ์„ฑ ํ›„ operate ์ถ”์ƒ๋ฉ”์„œ๋“œ ์ƒ์„ฑ
  • ๊ธฐ๋Šฅ ํด๋ž˜์Šค์—์„œ ์ถ”์ƒํด๋ž˜์Šค๋ฅผ ์ƒ์†ํ•˜๊ณ  ์˜ค๋ฒ„๋ผ์ด๋”ฉ
  • Divide์—์„œ ๋‚˜๋ˆ„๊ธฐ 0์ด ๋ถˆ๊ฐ€๋Šฅํ•œ ์˜ˆ์™ธ๋ฅผ ์ถ”๊ฐ€์ ์œผ๋กœ ์ฒ˜๋ฆฌ
  • (์ดํ•ด ์•ˆ ๋จ) Calculator ํด๋ž˜์Šค๋Š” ์ƒ์„ฑ์ž๋ฅผ ํ†ตํ•ด operator๋ผ๋Š” ์ด๋ฆ„์˜ AbstractOperation ํƒ€์ž… ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ๋ฐ›๋Š”๋‹ค.
    ์ด ๋งค๊ฐœ๋ณ€์ˆ˜๋Š” Calculator์˜ ์ธ์Šคํ„ด์Šค๋ฅผ ์ƒ์„ฑํ•  ๋•Œ ์ œ๊ณต๋˜๋Š” ์—ฐ์‚ฐ์ž ์ข…๋ฅ˜๋ฅผ ๋‚˜ํƒ€๋‚ธ๋‹ค.
    operate ํ•จ์ˆ˜๋Š” ๋‘ ๊ฐœ์˜ ์ •์ˆ˜๋ฅผ ๋ฐ›์•„๋“ค์ด๊ณ , operator๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํ•ด๋‹น ์—ฐ์‚ฐ์„ ์ˆ˜ํ–‰ํ•œ ๋’ค Double ๊ฒฐ๊ณผ๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค.
    ์—ฌ๊ธฐ์„œ operator ๊ฐ์ฒด์˜ ์‹ค์ œ ๋™์ž‘์€ AbstractOperation ํด๋ž˜์Šค๋ฅผ ๊ตฌํ˜„ํ•œ ํ•˜์œ„ ํด๋ž˜์Šค์— ์˜ํ•ด ๊ฒฐ์ •๋œ๋‹ค.
  • ๊ฒฐ๊ณผ์ ์œผ๋กœ ๋ง์…ˆ๊ณ„์‚ฐ๊ธฐ, ๋บ„์…ˆ๊ณ„์‚ฐ๊ธฐ, ๊ณฑ์…ˆ๊ณ„์‚ฐ๊ธฐ๋ฅผ ์ผ์ผํžˆ ๋ถˆ๋Ÿฌ์˜ค๋Š” ๊ฒŒ ์•„๋‹ˆ๋ผ ๋‹ค ๊ฐ™์ด ๊ณ„์‚ฐ๊ธฐ๋ฅผ ๋ถˆ๋Ÿฌ์˜ค๊ฒŒ ๋œ๋‹ค.

 

 

DIP (์˜์กด์„ฑ ์—ญ์ „ ์›์น™)

 

 

 

 


 

4. ๊ธฐ๋Šฅ ์ถ”๊ฐ€ (3๊ฐœ ์ด์ƒ์˜ ์ˆ˜ ์—ฐ์‚ฐ ์‹œ ๋ถ€ํ˜ธ ์šฐ์„  ์ˆœ์œ„, ๊ด„ํ˜ธ ์‚ฌ์šฉ ์‹œ ์šฐ์„  ์ˆœ์œ„ ๋“ฑ)

 

๋”๋ณด๊ธฐ
Main.kt

fun main() {
    val addCalc = Calculator(AddOperation())
    println("10๋”ํ•˜๊ธฐ 20 ๊ฒฐ๊ณผ๋Š” : ${addCalc.operate(10, 20)} ์ž…๋‹ˆ๋‹ค")

    val minusCalc = Calculator(SubstractOperation())
    println("20๋นผ๊ธฐ 10 ๊ฒฐ๊ณผ๋Š” : ${minusCalc.operate(20, 10)} ์ž…๋‹ˆ๋‹ค")

    val multipleCalc = Calculator(MultiplyOperation())
    println("10๊ณฑํ•˜๊ธฐ 20 ๊ฒฐ๊ณผ๋Š” : ${multipleCalc.operate(10, 20)} ์ž…๋‹ˆ๋‹ค")

    val divideCalc = Calculator(DivideOperation())
    println("20๋‚˜๋ˆ„๊ธฐ 10 ๊ฒฐ๊ณผ๋Š” : ${divideCalc.operate(20, 10)} ์ž…๋‹ˆ๋‹ค")

    val myStack = MyStack()
    val calResult = myStack.getPostFixExpressionOperation("(2 + 4) * 4 / 2 * 12")
    println("๊ฒฐ๊ณผ: ${calResult}์ž…๋‹ˆ๋‹ค")
}
Calculator.kt, ๊ธฐ๋ŠฅOperation.kt ๋ชจ๋‘ ์œ„์˜ 3๋ฒˆ๊ณผ ๋™์ผ
MyStack.kt

class MyStack {
    fun getPostFixExpressionOperation(originalExpression: String): Int {
        val stack = Stack<String>()
        val arr = strToArr(originalExpression)
        var result = ""

        for(e in arr) {
            when(e) {
                "+", "-", "*", "/" -> {
                    while(!stack.isEmpty() && precedence(stack.peek()) >= precedence(e)) {
                        result += stack.pop() + " "
                    }
                    stack.push(e)
                }
                "(" -> {
                    stack.push(e)
                }
                ")" -> {
                    while(stack.peek() != "(") {
                        result += stack.pop() + " "
                    }
                    stack.pop() // "(" ์ œ๊ฑฐ
                }
                else -> {
                    result += "$e "
                }
            }
        }

        while(!stack.isEmpty()) {
            result += stack.pop() + " "
        }

        println("---์ตœ์ข…---")
        println("ํ›„์œ„ํ‘œ๊ธฐ๋ฒ•: $result")

        val realResult = finalCalc(result)
        println("๊ฒฐ๊ณผ: $realResult")
        return realResult
    }

    fun finalCalc(result: String): Int {
        val stack = Stack<String>()
        val calResult = result.split(" ")
        var result = 0

        for(e in calResult) {
            when(e) {
                "+" -> {
                    result = stack.pop().toInt() + stack.pop().toInt()
                    stack.push(result.toString())
                }
                "-" -> {
                    result = -stack.pop().toInt() + stack.pop().toInt()
                    stack.push(result.toString())
                }
                "*" -> {
                    result = stack.pop().toInt() * stack.pop().toInt()
                    stack.push(result.toString())
                }
                "/" -> {
                    val num2 = stack.pop().toInt()
                    val num1 = stack.pop().toInt()
                    result = num1 / num2
                    stack.push(result.toString())
                }
                else -> {
                    stack.push(e)
                }
            }
        }
        return result
    }

    fun strToArr(str: String): Array<String> {
        var tempStr = str.replace("(", "( ")
        tempStr = tempStr.replace(")", " )")
        return tempStr.split(" ").toTypedArray()
    }

    fun precedence(operator: String): Int {
        return when(operator) {
            "+", "-" -> 1
            "*", "/" -> 2
            else -> 0
        }
    }
}
  • ์šฐ์„  ์ˆœ์œ„ ์ฒ˜๋ฆฌ๋ฅผ ์œ„ํ•ด Stack๊ณผ ํ›„์œ„ ์—ฐ์‚ฐ์˜ ๊ฐœ๋…์„ ์•Œ์•„์•ผ ํ•œ๋‹ค.
  • ์—ฐ์‚ฐ์ž ์šฐ์„  ์ˆœ์œ„
    (1) ( ) 
    (2) * / %
    (4) + -
  • ๋ฌธ๋ฒ• ๊ณต๋ถ€๋ฅผ ๋‹ค ํ•œ๋’ค 3์›” 15์ผ์— ๋‹ค์‹œ ๋Œ์•„์˜ค์ž

 

 

 

๋ฐ˜์‘ํ˜•
 ๐Ÿ’ฌ C O M M E N T