스팀 앱 개발기 #28 - Use Case 패턴 적용

in kr-dev 커뮤니티2 years ago (edited)

시작하며...

지난 포스트에서는 Repository 패턴을 적용하고 SteemRepository 인터페이스를 구현하면서 condenser_api.get_accounts API를 연동하는 과정을 보여 드렸습니다. 뷰 담당 모듈이 SteemRepository 구현 객체를 바로 사용하지는 않구요. Use Case 패턴 추가 적용 후에 정의할 UseCase 객체를 사용 가능하게 할 것입니다. 이게 클린 아키텍처에 의한 것이구요. 다음 포스트에서 각종 패턴들의 관계에 대해 설명을 드릴 예정입니다.


Use Case 패턴과 Repository 패턴의 관계

Use Case 객체가 Repository 객체를 참조합니다. 따라서 후자는 전자의 필드가 됩니다. 이를 코드로 나타내면 다음과 같습니다.

class ExampleUseCase(val repository: ExampleRepository) {
    // ...
}

dorian-steem-domain 모듈에 ReadSteemitWalletUseCase 클래스 정의

위에 설명 드린 것을 베이스로 ReadSteemitWalletUseCase 클래스를 작성해 보겠습니다. 클래스 이름은요. SteemRepository 인터페이스에 선언된 메소드 이름을 따왔습니다. 클래스 이름만 보고도 어떤 API를 실행하고 어떤 자료를 받아오는지를 알 수 있게 하는 것입니다. 참조할 Repository 인터페이스는 이전에 정의한 SteemRepository죠. 추가할 메소드는 invoke이며, 이것은 필요한 API를 실행할 SteemRepository 인터페이스의 메소드를 호출합니다.

class ReadSteemitWalletUseCase(val steemRepository: SteemRepository) {

    operator fun invoke(account: String): Flowable<Array<SteemitWalletDTO>> {
        return steemRepository.readSteemitWallet(account)
    }

}

참고로 invoke 메소드 선언의 맨 앞에 operator 키워드가 있죠. 이게 있으면, ReadSteemitWalletUseCase 객체의 invoke 메소드를 호출할 때 메소드 이름을 생략하고 파라메터만 사용할 수 있습니다. 예를 들면 아래와 같습니다.

val steemRepository = SteemRepositoryImpl()
val readSteemitWalletUseCase = ReadSteemitWalletUseCase(steemRepository)

// 이렇게도 호출 가능
readSteemitWalletUseCase.invoke("dorian-mobileapp")

// 요렇게도 호출 가능
readSteemitWalletUseCase("dorian-mobileapp")

ReadSteemitWalletUseCase 클래스 테스트

유닛 테스트를 이용하여 이 클래스가 잘 작동하는지 테스트할 수 있습니다. ReadSteemitWalletUseCase 클래스는 dorian-steem-domain 모듈에 속해 있지만, 테스트 클래스는 dorian-steem-data 모듈에 정의합니다. 왜냐면 ReadSteemitWalletUseCase가 참조할 SteemRepository 구현 객체가 dorian-steem-domain 모듈에 위치하기 때문입니다.

테스트 클래스 이름은 ReadSteemitWalletUseCaseTest이며, 테스트 코드는 다음과 같이 작성했습니다. SteemRepositoryTest와 비슷합니다.

class ReadSteemitWalletUseCaseTest {

    val readSteemitWalletUseCase = ReadSteemitWalletUseCase(SteemRepositoryImpl())

    // Test case 1: Trying to get the wallet of a valid account.
    @Test
    fun invoke_case1() {
        readSteemitWalletUseCase(TestData.singleAccount).subscribe { wallets ->
            Assert.assertEquals(1, wallets.size)
            Assert.assertEquals(TestData.singleAccount, wallets[0].account)
        }
    }

    // Test case 2: Trying to get the wallet of an invalid account.
    @Test
    fun invoke_case2() {
        readSteemitWalletUseCase(TestData.invalidSingleAccount).subscribe { wallets ->
            Assert.assertEquals(0, wallets.size)
        }
    }

}

테스트 결과, SteemitWalletDTO 타입의 지갑 정보를 읽을 수 있음을 확인했습니다.

image.png


GitHub Commit


마치며...

드디어 Use Case 패턴도 적용했습니다. 다음 포스트에서는 지금까지 추가한 패턴들의 역할과 관계에 대하여 간략히 정리해 보고자 합니다. 무엇을 개발하는 것도 중요하지만, '어떻게'와 '왜' 또한 중요하기 때문입니다.


지난 스팀 앱 개발기

Sort:  
 2 years ago 

[광고] STEEM 개발자 커뮤니티에 참여 하시면, 다양한 혜택을 받을 수 있습니다.

Upvoted! Thank you for supporting witness @jswit.

Coin Marketplace

STEEM 0.18
TRX 0.14
JST 0.029
BTC 57849.42
ETH 3122.29
USDT 1.00
SBD 2.43