feat : SOLID - SRP 샘플 코드 구현
This commit is contained in:
24
놀이터(예제 코드 작성)/solid-design-pattern-sample/README.md
Normal file
24
놀이터(예제 코드 작성)/solid-design-pattern-sample/README.md
Normal file
@@ -0,0 +1,24 @@
|
||||
# SOLID & Design Pattern Sample
|
||||
|
||||
## SOLID
|
||||
|
||||
- SOLID 원칙들은 소프트웨어 작업에서 프로그래머가 소스 코드가 읽기 쉽고 확장하기 쉽게 될 때까지 소프트웨어 소스 코드를 리팩터링하여 코드 냄새를 제거하기 위해 적용할 수 있는 지침이다.
|
||||
- 각 항목별 before & after 를 비교하면서 어떤 차이가 있는지 생각해본다.
|
||||
- before & after 에 새로운, 또는 동일한 규칙(비즈니스 로직, 유효성 검사 등)을 적용해야 한다고 가정하고 변경을 시도해본다.
|
||||
|
||||
### SRP(Single Responsibility Principle)
|
||||
|
||||
- 단일 책임 원칙
|
||||
- 한 클래스는 하나의 책임만 가져야 한다. 즉, 한 클래스가 변경되는 이유는 한 가지여야 한다.
|
||||
|
||||
#### 구현 요구사항
|
||||
|
||||
- 예금주의 이름으로 계좌를 생성할 수 있다.
|
||||
- 계좌에 입금할 수 있다.
|
||||
- 계좌에서 출금할 수 있다.
|
||||
|
||||
## 참고자료
|
||||
|
||||
- [SOLID (객체 지향 설계)](https://ko.wikipedia.org/wiki/SOLID_(%EA%B0%9D%EC%B2%B4_%EC%A7%80%ED%96%A5_%EC%84%A4%EA%B3%84))
|
||||
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
package com.banjjoknim.soliddesignpatternsample.solid.srp.after
|
||||
|
||||
import com.banjjoknim.soliddesignpatternsample.solid.srp.common.Account
|
||||
import org.springframework.web.bind.annotation.PostMapping
|
||||
import org.springframework.web.bind.annotation.RequestBody
|
||||
import org.springframework.web.bind.annotation.RequestMapping
|
||||
import org.springframework.web.bind.annotation.RestController
|
||||
|
||||
@RequestMapping("/accounts")
|
||||
@RestController
|
||||
class CreateAccountController(
|
||||
private val createAccountService: CreateAccountService
|
||||
) {
|
||||
@PostMapping("")
|
||||
fun createAccount(@RequestBody request: CreateAccountRequest): Account {
|
||||
return createAccountService.createAccount(request)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
package com.banjjoknim.soliddesignpatternsample.solid.srp.after
|
||||
|
||||
data class CreateAccountRequest(
|
||||
val holderName: String
|
||||
)
|
||||
@@ -0,0 +1,14 @@
|
||||
package com.banjjoknim.soliddesignpatternsample.solid.srp.after
|
||||
|
||||
import com.banjjoknim.soliddesignpatternsample.solid.srp.common.Account
|
||||
import com.banjjoknim.soliddesignpatternsample.solid.srp.common.AccountRepository
|
||||
import org.springframework.stereotype.Service
|
||||
|
||||
@Service
|
||||
class CreateAccountService(
|
||||
private val accountRepository: AccountRepository
|
||||
) {
|
||||
fun createAccount(request: CreateAccountRequest): Account {
|
||||
return accountRepository.createAccount(request.holderName)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package com.banjjoknim.soliddesignpatternsample.solid.srp.after
|
||||
|
||||
import com.banjjoknim.soliddesignpatternsample.solid.srp.common.Account
|
||||
import org.springframework.web.bind.annotation.PatchMapping
|
||||
import org.springframework.web.bind.annotation.RequestBody
|
||||
import org.springframework.web.bind.annotation.RequestMapping
|
||||
import org.springframework.web.bind.annotation.RestController
|
||||
|
||||
@RequestMapping("/accounts")
|
||||
@RestController
|
||||
class DepositAccountController(
|
||||
private val depositAccountService: DepositAccountService
|
||||
) {
|
||||
@PatchMapping("/deposit")
|
||||
fun depositAccount(@RequestBody request: DepositAccountRequest): Account {
|
||||
return depositAccountService.depositAccount(request)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
package com.banjjoknim.soliddesignpatternsample.solid.srp.after
|
||||
|
||||
data class DepositAccountRequest(
|
||||
val accountId: Long,
|
||||
val amount: Int
|
||||
)
|
||||
@@ -0,0 +1,16 @@
|
||||
package com.banjjoknim.soliddesignpatternsample.solid.srp.after
|
||||
|
||||
import com.banjjoknim.soliddesignpatternsample.solid.srp.common.Account
|
||||
import com.banjjoknim.soliddesignpatternsample.solid.srp.common.AccountRepository
|
||||
import org.springframework.stereotype.Service
|
||||
|
||||
@Service
|
||||
class DepositAccountService(
|
||||
private val accountRepository: AccountRepository
|
||||
) {
|
||||
fun depositAccount(request: DepositAccountRequest): Account {
|
||||
val account = accountRepository.findAccount(request.accountId)
|
||||
account.deposit(request.amount)
|
||||
return account
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package com.banjjoknim.soliddesignpatternsample.solid.srp.after
|
||||
|
||||
import com.banjjoknim.soliddesignpatternsample.solid.srp.common.Account
|
||||
import org.springframework.web.bind.annotation.PatchMapping
|
||||
import org.springframework.web.bind.annotation.RequestBody
|
||||
import org.springframework.web.bind.annotation.RequestMapping
|
||||
import org.springframework.web.bind.annotation.RestController
|
||||
|
||||
@RequestMapping("/accounts")
|
||||
@RestController
|
||||
class WithdrawalAccountController(
|
||||
private val withdrawalAccountService: WithdrawalAccountService
|
||||
) {
|
||||
@PatchMapping("/withdrawal")
|
||||
fun withdrawal(@RequestBody request: WithdrawalAccountRequest): Account {
|
||||
return withdrawalAccountService.withdrawalAccount(request)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
package com.banjjoknim.soliddesignpatternsample.solid.srp.after
|
||||
|
||||
data class WithdrawalAccountRequest(
|
||||
val accountId: Long,
|
||||
val amount: Int
|
||||
)
|
||||
@@ -0,0 +1,16 @@
|
||||
package com.banjjoknim.soliddesignpatternsample.solid.srp.after
|
||||
|
||||
import com.banjjoknim.soliddesignpatternsample.solid.srp.common.Account
|
||||
import com.banjjoknim.soliddesignpatternsample.solid.srp.common.AccountRepository
|
||||
import org.springframework.stereotype.Service
|
||||
|
||||
@Service
|
||||
class WithdrawalAccountService(
|
||||
private val accountRepository: AccountRepository
|
||||
) {
|
||||
fun withdrawalAccount(request: WithdrawalAccountRequest): Account {
|
||||
val account = accountRepository.findAccount(request.accountId)
|
||||
account.withdrawal(request.amount)
|
||||
return account
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package com.banjjoknim.soliddesignpatternsample.solid.srp.before
|
||||
|
||||
import com.banjjoknim.soliddesignpatternsample.solid.srp.common.Account
|
||||
import org.springframework.web.bind.annotation.PatchMapping
|
||||
import org.springframework.web.bind.annotation.RequestBody
|
||||
import org.springframework.web.bind.annotation.RequestMapping
|
||||
import org.springframework.web.bind.annotation.RestController
|
||||
|
||||
@RequestMapping("/accounts")
|
||||
@RestController
|
||||
class AccountControllerBefore(
|
||||
private val accountServiceBefore: AccountServiceBefore
|
||||
) {
|
||||
@PatchMapping("/manage-account-before")
|
||||
fun manageAccount(@RequestBody request: ManageAccountRequest): Account {
|
||||
return accountServiceBefore.manageAccount(request)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
package com.banjjoknim.soliddesignpatternsample.solid.srp.before
|
||||
|
||||
import com.banjjoknim.soliddesignpatternsample.solid.srp.common.Account
|
||||
import com.banjjoknim.soliddesignpatternsample.solid.srp.common.AccountRepository
|
||||
import org.springframework.stereotype.Service
|
||||
|
||||
@Service
|
||||
class AccountServiceBefore(
|
||||
private val accountRepository: AccountRepository
|
||||
) {
|
||||
fun manageAccount(request: ManageAccountRequest): Account {
|
||||
return when (request.type) {
|
||||
ManageAccountType.CREATE -> {
|
||||
accountRepository.createAccount(request.holderName)
|
||||
}
|
||||
ManageAccountType.DEPOSIT -> {
|
||||
val account = accountRepository.findAccount(request.accountId)
|
||||
account.deposit(request.amount)
|
||||
account
|
||||
}
|
||||
ManageAccountType.WITHDRAWAL -> {
|
||||
val account = accountRepository.findAccount(request.accountId)
|
||||
account.withdrawal(request.amount)
|
||||
account
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
package com.banjjoknim.soliddesignpatternsample.solid.srp.before
|
||||
|
||||
data class ManageAccountRequest(
|
||||
val accountId: Long,
|
||||
val holderName: String,
|
||||
val amount: Int,
|
||||
val type: ManageAccountType
|
||||
)
|
||||
@@ -0,0 +1,7 @@
|
||||
package com.banjjoknim.soliddesignpatternsample.solid.srp.before
|
||||
|
||||
enum class ManageAccountType {
|
||||
CREATE, // 생성
|
||||
DEPOSIT, // 입금
|
||||
WITHDRAWAL // 출금
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package com.banjjoknim.soliddesignpatternsample.solid.srp.common
|
||||
|
||||
import javax.persistence.Entity
|
||||
import javax.persistence.Id
|
||||
|
||||
@Entity
|
||||
class Account(
|
||||
val holderName: String = "",
|
||||
var balance: Int = 0,
|
||||
@Id
|
||||
val id: Long = 0,
|
||||
) {
|
||||
fun deposit(amount: Int) {
|
||||
this.balance = this.balance + amount
|
||||
}
|
||||
|
||||
fun withdrawal(amount: Int) {
|
||||
this.balance = this.balance - amount
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package com.banjjoknim.soliddesignpatternsample.solid.srp.common
|
||||
|
||||
interface AccountRepository {
|
||||
fun createAccount(holderName: String): Account
|
||||
|
||||
fun findAccount(accountId: Long): Account
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package com.banjjoknim.soliddesignpatternsample.solid.srp.common
|
||||
|
||||
import org.springframework.stereotype.Repository
|
||||
|
||||
@Repository
|
||||
class AccountRepositoryStub : AccountRepository {
|
||||
override fun createAccount(holderName: String): Account {
|
||||
return Account(holderName = "banjjoknim", balance = 0)
|
||||
}
|
||||
|
||||
override fun findAccount(accountId: Long): Account {
|
||||
return Account(id = 1L, balance = 10000)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user