es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

¿Es buena práctica que un Jetpack ViewModel implemente una interfaz?

En un proyecto, cada Jetpack Viewmodel implementa una interfaz. Por ejemplo:

interface ExamReportViewModel : ActionSource<examreportviewmodel.action>,
    ExamExamineeListItem.Listener {

    val examReportId: StateFlow<string?>
    val examReportHeader: StateFlow<examreportheader?>
    val examExamineeList: StateFlow<><examexamineelistitem>>
    val isHeaderExpanded: StateFlow<boolean>

    fun setExamReportId(id: String)
    fun toggleHeaderExpanded()
    fun navigateToExtraordinaryEvent()

    sealed class Action {
        data class ToIdentificationDialog(val examReportId: String, val examineeId: String) : Action()
        data class ToEvaluation(val exam: Exam) : Action()
        object ToExtraordinaryEvent : Action()
    }
}

Una implementación real:

class ExamReportViewModelImpl @Inject constructor(
    private val examReportInteractor: ExamReportInteractor,
    private val errorDelegate: ErrorDelegate,
) : BaseViewModel(), ExamReportViewModel

¿Tiene sentido esto? ¿Cuáles serían las ventajas y desventajas?
Desventajas:
1) Las posibilidades de que el mismo ViewModel requiera 2 implementaciones diferentes son casi nulas.
2) Podemos ocultar la implementación MutableStateFlow en un campo privado dentro del ViewModel y simplemente usar .asStateFlow() para convertirlo en uno no mutable.
3) Es necesario declararlo.
4) Son testables con y sin la interfaz.
5) Complica la inyección con Dagger Hilt debido a que hay un BaseFragment que se basa en genéricos.

¿Hay alguna ventaja?

abstract class BaseFragment<t :="" any,="" b="" :="" viewdatabinding="">(
        open val contentViewId: Int,
    ) : DaggerFragment() {
@Inject
lateinit var viewModel: T
}

class ExamReportFragment :
        BaseFragment<examreportviewmodel, fragmentexamreportbinding="">(R.layout.fragment_exam_report) {
}

Con este enfoque no pude utilizar la extensión private val viewModel by viewModels<tasksviewmodel>(). No sé si es posible o si tiene sentido.</examreportviewmodel,></examreportheader?></string?></examreportviewmodel.action>

Tags:  , , , ,

Answer

  1. Avatar for davy.ai

    Pros:
    1) Impone una estructura clara y una separación de responsabilidades dentro del proyecto.
    2) Permite cambiar fácilmente las implementaciones del modelo de vista si es necesario en el futuro.
    3) Facilita las pruebas al proporcionar una interfaz clara con la que trabajar y simular.

    En general, aunque puede haber algunas desventajas, los beneficios de implementar interfaces para cada Viewmodel de Jetpack probablemente los superen en la mayoría de los proyectos.

Comments are closed.