Skip to content

Instantly share code, notes, and snippets.

@anantyan
Last active August 22, 2023 06:14
Show Gist options
  • Save anantyan/114b99962c2201b17fc9fd42d05f78d9 to your computer and use it in GitHub Desktop.
Save anantyan/114b99962c2201b17fc9fd42d05f78d9 to your computer and use it in GitHub Desktop.
Membagikan mengenai implementasi sebuah code pemrograman menggunakan MVVM + Clean Architecture pada studi kasus penyimpanan database menggunakan Cloud Firebase (Firestore) untuk Notepad
// 3. Repository Implementation (Data Layer)
class FirestoreNotesRepository @Inject constructor() : NotesRepository {
private val db = FirebaseFirestore.getInstance()
private val notesCollection = db.collection("notes")
override fun getNotes(): Flow<Resource> = flow {
emit(Resource.Loading)
try {
notesCollection.addSnapshotListener { snapshot, exception ->
if (exception != null || snapshot == null) {
emit(NoteState.Error(exception ?: Throwable("Unknown error occurred")))
return@addSnapshotListener
}
val notesList = snapshot.documents.mapNotNull { document ->
document.toObject(Note::class.java)
}
emit(NoteState.Success(notesList))
}
} catch (e: Exception) {
emit(NoteState.Error(e))
}
}
// ... other methods ...
}
// 1. Model (Domain Layer)
data class Note(
val id: String = "",
val title: String = "",
val content: String = ""
)
// 4. Dagger Hilt Module
@Module
@InstallIn(SingletonComponent::class)
object Module {
@Provides
@Singleton
fun provideNotesRepository(): NotesRepository = FirestoreNotesRepository()
}
// 2. Repository Interface (Domain Layer)
interface NotesRepository {
fun addNote(note: Note): Flow<Resource>
fun getNotes(): Flow<Resource>
fun updateNote(note: Note): Flow<Resource>
fun deleteNote(note: Note): Flow<Resource>
}
// 8. UI (Activity/Fragment) - a brief snippet
@AndroidEntryPoint
class NotesActivity : AppCompatActivity() {
private val viewModel: NoteViewModel by viewModels()
// ... rest of the code ...
viewModel.notesState.observe(this, Observer { state ->
when (state) {
is NoteState.Loading -> { /* ... */ }
is NoteState.Success -> { /* ... */ }
is NoteState.Error -> { /* ... */ }
}
})
}
// 6. ViewModel (Presentation Layer)
@HiltViewModel
class NoteViewModel @Inject constructor(
private val getNotesUseCase: GetNotesUseCase
// ... other use cases ...
) : ViewModel() {
val notesState: LiveData<Resource> = getNotesUseCase.invoke().asLiveData()
// ... other methods ...
}
// 7. Sealed Class for State
sealed class Resource {
object Loading : NoteState()
data class Success(val data: List<Note>) : NoteState()
data class Error(val exception: Throwable) : NoteState()
}
// 5. Use Case (Use Case Layer)
class GetNotesUseCase @Inject constructor(private val repository: NotesRepository) {
fun invoke(): Flow<Resource> {
return repository.getNotes()
}
}
// ... other Use Cases ...
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment