Skip to content

계산기 구현 #2

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions .idea/.gitignore

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions .idea/misc.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 8 additions & 0 deletions .idea/modules.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions .idea/vcs.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

30 changes: 30 additions & 0 deletions wooseok/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
### IntelliJ IDEA ###
.idea
out/
!**/src/main/**/out/
!**/src/test/**/out/

### Eclipse ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache
bin/
!**/src/main/**/bin/
!**/src/test/**/bin/

### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/

### VS Code ###
.vscode/

### Mac OS ###
.DS_Store
78 changes: 78 additions & 0 deletions wooseok/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
# kotlin_calculator
코틀린 계산기 구현 미션 Repository입니다.<br>
❗각자 폴더만들고 그 안에 프로젝트를 만들어주세요! (0depth에 프로젝트가 올라가지않게 주의)

### 과제를 통해 기대하는 역량

- 기본적인 테스트 코드 작성 및 활용하는 능력해보자
- 스스로 OOP를 생각하고 코드로 옮길 수 있는 능력해보자

### 요구사항
- 콘솔로 구현입니다.(스윙으로 구현하시는 분들 계실까봐)
- 객체지향적인 코드로 계산기 구현하기
- [ ] 더하기
- [ ] 빼기
- [ ] 곱하기
- [ ] 나누기
- [ ] 우선순위(사칙연산)
- [ ] 테스트 코드 구현하기
- [ ] 계산 이력을 맵으로 데이터 저장기능 만들기
- 애플리케이션이 동작하는 동안 데이터베이스 외에 데이터를 저장할 수 있는 방법을 고안해보세요.
- (선택) 정규식 사용

### 실행결과(콘솔)
```
1. 조회
2. 계산

선택 : 2

1 + 2
3

1. 조회
2. 계산

선택 : 2

1 + 2 * 3
7

1. 조회
2. 계산

선택 : 1

1 + 2 = 3
1 + 2 * 3 = 7

선택 : 2

3 - 2 * 2
-1
```

# 요구사항 분석
## 비즈니스 로직
### 연산
1. 왼쪽부터 오른쪽으로 사칙연산 중 곱하기(*), 나누기(/) 부터 연산한다.
2. 왼쪽부터 오른쪽으로 사칙연산 중 더하기(+), 빼기(-) 를 연산한다.

### 조회
1. 식을 저장한다.
2. 연산 완료된 값을 저장한다.

## 도메인 별 역할
### Expression
- 숫자를 받으면 연산한 결과값을 반환할 수 있다.
- 연산자와 숫자를 가지고 있다.
- EmptyExpression은 연산할 경우 전달받은 숫자를 그대로 반환한다.

### Operator
- 연산자에 맞게 연산할 수 있다.
- 연산자끼리의 연산 우선순위를 비교할 수 있다.
- 사칙연산이 구현되어 있다.

## 그 외 객체의 역할
- controller: 프로그램의 프로세스를 관리할 수 있다.
- repository: 연산 결과를 저장하고 조회할 수 있다.
38 changes: 38 additions & 0 deletions wooseok/src/main/kotlin/Main.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import controller.CalculationController
import controller.EndController
import controller.InquiryController

fun main(args: Array<String>) {

val inquiryController = InquiryController()
val calculationController = CalculationController()
val endController = EndController()

running@ while (true) {
when (choiceController()) {
1 -> inquiryController.run()
2 -> calculationController.run()
3 -> {
endController.run()
break@running
}
else -> {
println("해당 번호에 맞는 기능이 없습니다. 다시 입력해주세요.")
inquiryController.run()
}
}
}
}

fun choiceController(): Int {
print(
"""
1. 조회
2. 계산
3. 종료
선택 :
""".trimIndent()
)

return readln().toInt()
}
21 changes: 21 additions & 0 deletions wooseok/src/main/kotlin/controller/CalculationController.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package controller

import domain.*
import repository.CalculationRepository

class CalculationController: Controller {

override fun run() {
val readLine = readLine()
val strings: List<String> = readLine?.split(" ")!!

val startNumber: Int = strings[0].toInt()
var expression: Expression = EmptyExpression();
for (index in strings.size-1 downTo 2 step 2) {
expression = CalculateExpression(strings[index].toInt(), Operator.of(strings[index-1]), expression)
}
val result = expression.calculate(startNumber)
CalculationRepository.save(CalculationResult(strings.joinToString(" "), result.toString()))
println(result)
}
}
6 changes: 6 additions & 0 deletions wooseok/src/main/kotlin/controller/Controller.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package controller

interface Controller {

fun run()
}
8 changes: 8 additions & 0 deletions wooseok/src/main/kotlin/controller/EndController.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package controller

class EndController: Controller {

override fun run() {
println("계산기를 종료합니다.")
}
}
14 changes: 14 additions & 0 deletions wooseok/src/main/kotlin/controller/InquiryController.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package controller

import domain.*
import repository.CalculationRepository

class InquiryController(): Controller {

override fun run() {
val calculationResults: List<CalculationResult> = CalculationRepository.findAll()
for (calculationResult in calculationResults) {
println(calculationResult.expression + " = " + calculationResult.result)
}
}
}
19 changes: 19 additions & 0 deletions wooseok/src/main/kotlin/domain/CalculateExpression.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package domain

open class CalculateExpression(
override val number: Int,
override val operator: Operator,
val nextExpression: Expression = EmptyExpression(),
override val isEnd: Boolean = false
) : Expression {

override fun calculate(number: Int): Int {
if (nextExpression.isEnd) {
return operator.operate(number, this.number)
}
if (operator.isPrecede(nextExpression.operator)) {
return nextExpression.calculate(operator.operate(number, this.number))
}
return operator.operate(number, nextExpression.calculate(this.number))
}
}
3 changes: 3 additions & 0 deletions wooseok/src/main/kotlin/domain/CalculationResult.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package domain

data class CalculationResult(val expression: String, val result: String)
14 changes: 14 additions & 0 deletions wooseok/src/main/kotlin/domain/EmptyExpression.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package domain

class EmptyExpression : Expression {
override val number: Int
get() = 0
override val operator: Operator
get() = Operator.ADDITION

override val isEnd: Boolean = true

override fun calculate(number: Int): Int {
return number
}
}
10 changes: 10 additions & 0 deletions wooseok/src/main/kotlin/domain/Expression.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package domain

interface Expression {

val number: Int
val operator: Operator
val isEnd: Boolean

fun calculate(number: Int): Int
}
39 changes: 39 additions & 0 deletions wooseok/src/main/kotlin/domain/Operator.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package domain

import java.util.*

enum class Operator(val orderNumber: Int, val symbol: String) {

ADDITION(0, "+") {
override fun operate(number1: Int, number2: Int): Int {
return number1 + number2
}
},
SUBSTRACTION(0, "-") {
override fun operate(number1: Int, number2: Int): Int {
return number1 - number2
}
},
MULTIPLICATION(1, "*") {
override fun operate(number1: Int, number2: Int): Int {
return number1 * number2
}
},
DIVISION(1, "/") {
override fun operate(number1: Int, number2: Int): Int {
return number1 / number2
}
}
;

abstract fun operate(number1: Int, number2: Int): Int
fun isPrecede(other: Operator): Boolean {
return orderNumber > other.orderNumber
}

companion object {
fun of(symbol: String): Operator {
return entries.first { it.symbol == symbol }
}
}
}
16 changes: 16 additions & 0 deletions wooseok/src/main/kotlin/repository/CalculationRepository.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package repository

import domain.CalculationResult

object CalculationRepository {

val store: MutableList<CalculationResult> = mutableListOf()

fun save(calculationResult: CalculationResult) {
store.add(calculationResult)
}

fun findAll(): List<CalculationResult> {
return store.toList()
}
}
15 changes: 15 additions & 0 deletions wooseok/wooseok.iml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src/main/kotlin" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/main/resources" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/test/kotlin" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/test/resources" type="java-test-resource" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" name="KotlinJavaRuntime" level="project" />
</component>
</module>