Web Application 요구사항

황승현·2023년 12월 18일
0

스프링 강의 정리

목록 보기
2/8
post-thumbnail

Web Application 만들기 위한 요구사항

  • 유저 혹은 Frontend Application의 요청을 처리하고, 적절한 응답을 줄 수 있어야 한다.

  • 예외 처리를 할 수 있고, 예외가 발생했을 때 적절한 응답을 줄 수 있어야 한다.

    • 100원을 송금하려고 할 때, 계좌에 돈이 없는 상황은 예외 처리를 해줘야 됨
  • 인증과 인가 처리를 할 수 있어야 한다.

  • 비즈니스 로직을 처리할 수 있어야 한다.

  • 트랜잭션(Transaction) 관리 전략이 있어야 한다.

    • 트랜잭션(Transaction) : 상태를 변화하는 하나의 작업 단위
  • 스토리지다른 외부 시스템과 통신할 수 있어야 한다.

    • 스토리지(Storage) :

    • 외부 시스템 : 아마존 AWS 등

pseudo code

은행 계좌 클래스

// 내부 변수들을 쉽게 얻고(get). 수정(set)하기 위해서 data class 선언
// address : 계좌 주소
// balance : 계좌 잔액
// userID : 유저 아이디, 원래는 유저 클래스가 가지고 있어야하지만 지금은 BankAccount가 가지고 있다고 설정
data class BankAccount(val address: String, var balance: Int, val userID: String) {
    
}

송금 리퀘스트 보내는 클래스

// 내부 변수들을 쉽게 얻고(get). 수정(set)하기 위해서 data class 선언
// amount : 송금 금액
// fromAddress : 돈을 보내는 계좌 주소
// toAddress : 돈을 받는 계좌 주소
// userID : 송금하려는 유저의 아이디
data class TransferRequest(val amount: Int, val fromAddress : String, val toAddress: String, val userId: String) {


}

송금 리퀘스트 받는 클래스

// 내부 변수들을 쉽게 얻고(get). 수정(set)하기 위해서 data class 선언
// success : 전송 성공 여부
// message : 전송 메시지
data class TransferResponse(val success: Boolean, val message: String) {

}

송금 기능 클래스

class TransferService {
    
    // 은행 계좌 리스트
    // 현재는 메모리에 저장되기 때문에 어플이 종료되면 얘들도 사라짐
    // 원래는 데이터베이스에 저장되야 됨
    private val bankAccounts = listOf<BankAccount>(
        BankAccount(address = "abc", balance = 100, userID = "a"),
        BankAccount(address = "abcd", balance = 200, userID = "b")
    )
    
    //request를 받으면 응답을 줘야 됨
    fun transfer(request: TransferRequest): TransferResponse{

        // 리퀘스트 보낸 쪽의 은행 계좌
        val senderAccount = getBankAccountByAddress(request.fromAddress)

        // 돈 받는 쪽 은행 계좌
        val receiverAccount = getBankAccountByAddress(request.toAddress)

        //실제 계좌 주인인지 확인하고 맞으면 인가
        if(!autehnticate(senderAccount, request.userId)){
            return TransferResponse(success = false, message = "Unauthorized")
        }
        
        // 보내는 금액 확인
        if(request.amount < 0){ //송금액이 음수일 경우
            return TransferResponse(success = false, message = "Invalid amount")
        }

        // 보내는 주소, 받는 주소가 실제로 존재하는지 확인
        if (!isValidAddress(request.fromAddress) || !isValidAddress(request.toAddress)){
            return TransferResponse(success = false, message = "Invalid address")
        }
        
        // 돈을 송금하는 계좌에 돈이 충분히 있는지 확인
        if(!isSufficientBalance(senderAccount, request.amount)){
            return TransferResponse(success = false, message = "No sufficient balance")
        }
        
        /*==============동시에 이뤄져야 됨=================*/
        senderAccount.balance -= request.amount // 돈을 보내는 쪽 계좌에서 송금 금액만큼 돈이 빠져나감
        receiverAccount.balance += request.amount // 송금 금액만큼 돈을 받는 쪽 계좌의 금액을 늘려줌
        /*==============동시에 이뤄져야 됨=================*/
        
        return TransferResponse(success = true, message = "Succeed!!")
    }

    // 실제 계좌 주인인지 인증하는 메소드
    private fun autehnticate(bankAccount: BankAccount, userId: String):Boolean{
        return bankAccount.userID == userId
    }

    //실제 계좌가 존재하는지 체크하는 메소드
    private fun isValidAddress(address: String): Boolean{
        // bankAccounts에 address가 있다면 true 반환
        // bankAccounts에 address가 있다면 false 반환
        return bankAccounts.any{ it.address == address}
    }

    //계좌에 송금하는 금액만큼 돈이 존재하는지 확인
    private fun isSufficientBalance(bankAccount: BankAccount, amount: Int): Boolean{
        return bankAccount.balance >= amount
    }

    //주소 기반으로 은행계좌 가져옮
    private fun getBankAccountByAddress(address: String): BankAccount{
        return bankAccounts.first { it.address == address}
    }
}

0개의 댓글