feature/reader/viewmodel/ReaderViewModel.kt
cardReaderUseCase(ReaderType.PAYON, tag).collect { result ->
when(result){
is CardResult.Loading -> {
_uiEvent.emit(UiEvent.Loading(result.isLoading))
}
is CardResult.Success -> {
_uiEvent.emit(
UiEvent.ShowDialog(
"카드인식 성공",
"Card : ${Util().bytesToHex(result.data.track2Data)}"
)
)
}
is CardResult.Error -> {
_uiEvent.emit(UiEvent.ShowDialog(result.code, result.message))
}
}
}
core/domain/usecase
class CardReaderUseCase @Inject constructor(
private val repository: CardReaderRepository
) {
suspend operator fun invoke(type: ReaderType, tag: Tag): Flow<CardResult> {
return repository.readCard(type, tag)
}
}
core/domain/repository
interface CardReaderRepository {
suspend fun readCard(type: ReaderType, tag: Tag): Flow<CardResult>
}
enum class ReaderType {
PAYON,
SAMSUNG_PAY
}
core/data/repository
class CardReaderRepositoryImpl @Inject constructor(
private val dataSource: CardReaderDataSource
) : CardReaderRepository {
override suspend fun readCard(type: ReaderType, tag: Tag): Flow<CardResult> {
return dataSource.readCard(type, tag)
}
}
core/data/source
class CardReaderDataSource @Inject constructor(
private val factory: ReaderFactory
) {
suspend fun readCard(type: ReaderType, tag: Tag): Flow<CardResult> {
val reader = factory.getReader(type)
return reader.readCard(tag)
}
}
core/data/source/reader
interface ReaderStrategy {
suspend fun readCard(tag: Tag): Flow<CardResult>
}
class ReaderFactory @Inject constructor(
private val payonReader: ReaderStrategy,
private val samsungReader: ReaderStrategy
) {
fun getReader(type: ReaderType): ReaderStrategy = when (type) {
ReaderType.PAYON -> payonReader
ReaderType.SAMSUNG_PAY -> samsungReader
}
}
core/data/di
@Module
@InstallIn(SingletonComponent::class)
object ReaderModule {
@Provides
@Singleton
fun provideCardReaderRepository(
dataSource: CardReaderDataSource
): CardReaderRepository = CardReaderRepositoryImpl(dataSource)
}
viewModel → useCase 호출 → repository 호출 → dataSource 호출 → readerFactory에서 type에 따라 payon or samsungPay reader 선택