feat : SOLID - OCP 샘플 코드 구현
This commit is contained in:
@@ -17,6 +17,17 @@
|
||||
- 계좌에 입금할 수 있다.
|
||||
- 계좌에서 출금할 수 있다.
|
||||
|
||||
### OCP(Open/Closed 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,20 @@
|
||||
package com.banjjoknim.soliddesignpatternsample.solid.ocp.after
|
||||
|
||||
import com.banjjoknim.soliddesignpatternsample.solid.ocp.common.Payment
|
||||
import com.banjjoknim.soliddesignpatternsample.solid.ocp.common.PaymentRepository
|
||||
import com.banjjoknim.soliddesignpatternsample.solid.ocp.common.PaymentType
|
||||
import org.springframework.stereotype.Repository
|
||||
|
||||
@Repository
|
||||
class CardPaymentService(
|
||||
private val paymentRepository: PaymentRepository
|
||||
): PaymentServiceAfter {
|
||||
override fun pay(request: PaymentRequestAfter): Payment {
|
||||
println("카드 결제로 ${request.amount}원을 차감합니다.")
|
||||
return paymentRepository.createPayment(request.amount, request.paymentType)
|
||||
}
|
||||
|
||||
override fun getPaymentType(): PaymentType {
|
||||
return PaymentType.CARD
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package com.banjjoknim.soliddesignpatternsample.solid.ocp.after
|
||||
|
||||
import com.banjjoknim.soliddesignpatternsample.solid.ocp.common.Payment
|
||||
import com.banjjoknim.soliddesignpatternsample.solid.ocp.common.PaymentRepository
|
||||
import com.banjjoknim.soliddesignpatternsample.solid.ocp.common.PaymentType
|
||||
import org.springframework.stereotype.Repository
|
||||
|
||||
@Repository
|
||||
class CashPaymentService(
|
||||
private val paymentRepository: PaymentRepository
|
||||
): PaymentServiceAfter {
|
||||
override fun pay(request: PaymentRequestAfter): Payment {
|
||||
println("현금드 결제로 ${request.amount}원을 차감합니다.")
|
||||
return paymentRepository.createPayment(request.amount, request.paymentType)
|
||||
}
|
||||
|
||||
override fun getPaymentType(): PaymentType {
|
||||
return PaymentType.CASH
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package com.banjjoknim.soliddesignpatternsample.solid.ocp.after
|
||||
|
||||
import com.banjjoknim.soliddesignpatternsample.solid.ocp.common.Payment
|
||||
import com.banjjoknim.soliddesignpatternsample.solid.ocp.common.PaymentRepository
|
||||
import com.banjjoknim.soliddesignpatternsample.solid.ocp.common.PaymentType
|
||||
import org.springframework.stereotype.Repository
|
||||
|
||||
@Repository
|
||||
class CouponPaymentService(
|
||||
private val paymentRepository: PaymentRepository
|
||||
): PaymentServiceAfter {
|
||||
override fun pay(request: PaymentRequestAfter): Payment {
|
||||
println("쿠폰 결제는 잔고 차감이 없습니다.")
|
||||
return paymentRepository.createPayment(request.amount, request.paymentType)
|
||||
}
|
||||
|
||||
override fun getPaymentType(): PaymentType {
|
||||
return PaymentType.COUPON
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package com.banjjoknim.soliddesignpatternsample.solid.ocp.after
|
||||
|
||||
import com.banjjoknim.soliddesignpatternsample.solid.ocp.common.Payment
|
||||
import org.springframework.web.bind.annotation.PostMapping
|
||||
import org.springframework.web.bind.annotation.RequestMapping
|
||||
import org.springframework.web.bind.annotation.RestController
|
||||
|
||||
@RequestMapping("/payments")
|
||||
@RestController
|
||||
class PaymentController(
|
||||
private val paymentServiceFactory: PaymentServiceFactory
|
||||
) {
|
||||
@PostMapping("with-ocp")
|
||||
fun pay(request: PaymentRequestAfter): Payment {
|
||||
val paymentService = paymentServiceFactory.getPaymentService(request.paymentType)
|
||||
return paymentService.pay(request)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
package com.banjjoknim.soliddesignpatternsample.solid.ocp.after
|
||||
|
||||
import com.banjjoknim.soliddesignpatternsample.solid.ocp.common.PaymentType
|
||||
|
||||
data class PaymentRequestAfter(
|
||||
val amount: Int,
|
||||
val paymentType: PaymentType
|
||||
)
|
||||
@@ -0,0 +1,10 @@
|
||||
package com.banjjoknim.soliddesignpatternsample.solid.ocp.after
|
||||
|
||||
import com.banjjoknim.soliddesignpatternsample.solid.ocp.common.Payment
|
||||
import com.banjjoknim.soliddesignpatternsample.solid.ocp.common.PaymentType
|
||||
|
||||
interface PaymentServiceAfter {
|
||||
fun pay(request: PaymentRequestAfter): Payment
|
||||
|
||||
fun getPaymentType(): PaymentType
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package com.banjjoknim.soliddesignpatternsample.solid.ocp.after
|
||||
|
||||
import com.banjjoknim.soliddesignpatternsample.solid.ocp.common.PaymentType
|
||||
import org.springframework.stereotype.Component
|
||||
|
||||
@Component
|
||||
class PaymentServiceFactory(val paymentServices: List<PaymentServiceAfter>) {
|
||||
fun getPaymentService(paymentType: PaymentType): PaymentServiceAfter {
|
||||
return this.paymentServices.find { it.getPaymentType() == paymentType }
|
||||
?: throw NoSuchElementException("해당 결제방식에 대한 구현이 존재하지 않습니다.")
|
||||
}
|
||||
}
|
||||
|
||||
//@Component
|
||||
//class PaymentServiceFactory(
|
||||
// private val cashPaymentService: CashPaymentService,
|
||||
// private val cardPaymentService: CardPaymentService,
|
||||
// private val couponPaymentService: CouponPaymentService
|
||||
//) {
|
||||
// fun findPaymentService(paymentType: PaymentType): PaymentServiceAfter {
|
||||
// return when (paymentType) {
|
||||
// PaymentType.CASH -> cashPaymentService
|
||||
// PaymentType.CARD -> cardPaymentService
|
||||
// PaymentType.COUPON -> couponPaymentService
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
@@ -0,0 +1,18 @@
|
||||
package com.banjjoknim.soliddesignpatternsample.solid.ocp.before
|
||||
|
||||
import com.banjjoknim.soliddesignpatternsample.solid.ocp.common.Payment
|
||||
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("/payments")
|
||||
@RestController
|
||||
class PaymentControllerBefore(
|
||||
private val paymentServiceBefore: PaymentServiceBefore
|
||||
) {
|
||||
@PostMapping("/none-ocp")
|
||||
fun pay(@RequestBody request: PaymentRequestBefore): Payment {
|
||||
return paymentServiceBefore.pay(request)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
package com.banjjoknim.soliddesignpatternsample.solid.ocp.before
|
||||
|
||||
import com.banjjoknim.soliddesignpatternsample.solid.ocp.common.PaymentType
|
||||
|
||||
data class PaymentRequestBefore(
|
||||
val amount: Int,
|
||||
val type: PaymentType
|
||||
)
|
||||
@@ -0,0 +1,21 @@
|
||||
package com.banjjoknim.soliddesignpatternsample.solid.ocp.before
|
||||
|
||||
import com.banjjoknim.soliddesignpatternsample.solid.ocp.common.Payment
|
||||
import com.banjjoknim.soliddesignpatternsample.solid.ocp.common.PaymentRepository
|
||||
import com.banjjoknim.soliddesignpatternsample.solid.ocp.common.PaymentType
|
||||
import org.springframework.stereotype.Service
|
||||
|
||||
@Service
|
||||
class PaymentServiceBefore(
|
||||
private val paymentRepository: PaymentRepository
|
||||
) {
|
||||
fun pay(request: PaymentRequestBefore): Payment {
|
||||
when (request.type) {
|
||||
PaymentType.CASH -> println("현금 결제로 ${request.amount}원을 차감합니다.")
|
||||
PaymentType.CARD -> println("카드 결제로 ${request.amount}원을 차감합니다.")
|
||||
PaymentType.COUPON -> println("쿠폰 결제는 잔고 차감이 없습니다.")
|
||||
// NewPaymentType -> ...
|
||||
}
|
||||
return paymentRepository.createPayment(request.amount, request.type)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package com.banjjoknim.soliddesignpatternsample.solid.ocp.common
|
||||
|
||||
import javax.persistence.Entity
|
||||
import javax.persistence.Id
|
||||
|
||||
@Entity
|
||||
class Payment(
|
||||
val amount: Int,
|
||||
val type: PaymentType,
|
||||
@Id
|
||||
val id: Long = 0L
|
||||
)
|
||||
@@ -0,0 +1,5 @@
|
||||
package com.banjjoknim.soliddesignpatternsample.solid.ocp.common
|
||||
|
||||
interface PaymentRepository {
|
||||
fun createPayment(amount: Int, paymentType: PaymentType): Payment
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package com.banjjoknim.soliddesignpatternsample.solid.ocp.common
|
||||
|
||||
import org.springframework.stereotype.Repository
|
||||
|
||||
@Repository
|
||||
class PaymentRepositoryStub : PaymentRepository {
|
||||
override fun createPayment(amount: Int, paymentType: PaymentType): Payment {
|
||||
return Payment(amount = amount, type = paymentType)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package com.banjjoknim.soliddesignpatternsample.solid.ocp.common
|
||||
|
||||
enum class PaymentType {
|
||||
CASH,
|
||||
CARD,
|
||||
COUPON
|
||||
}
|
||||
Reference in New Issue
Block a user