Real-Clean-Architecture-In-Android---Sample icon indicating copy to clipboard operation
Real-Clean-Architecture-In-Android---Sample copied to clipboard

Question, UI display logic for model

Open h2yiwei opened this issue 4 months ago • 2 comments

Hi, I am new to Android modularization and I read your post on Medium — it is the best post about modularization I have ever read. Thanks for sharing it.

My question is:

If we add a ProductState enum in Product.kt, and we need a method that requires a Context to display the state in the UI, in which module should we put this method (getStateDisplayString)?

This method may be used in multiple UI modules, such as pip-ui and cart-ui.

// product-module
enum class ProductState {
   SOLD_OUT, 
   STOCK_IN;
} 

// where should this go?
fun getStateDisplayString(context: Context, state: ProductState): String {
    return when (state) {
        ProductState.SOLD_OUT -> {
            context.getString(context.getString(R.string.sold_out))
        }
        ProductState.IN_STOCK -> {
            context.getString(context.getString(R.string.in_stock))
        }
    }
}

h2yiwei avatar Oct 03 '25 10:10 h2yiwei

Hi, thanks for the kind words!

First, you’ll probably want to place that method in a UI mapper (for example, UIStockMapper) and prefer using Resources instead of Context, since it makes unit testing easier:

internal class RealUIStockMapper(private val resources: Resources): UIStockMapper {
    fun getStateDisplayString(state: ProductState): String {
        return when (state) {
            ProductState.SOLD_OUT -> {
                resources.getString(R.string.sold_out)
            }
            ProductState.IN_STOCK -> {
                resources.getString(R.string.in_stock)
            }
        }
    }
}

Alternatively, you could return the @StringRes Integer and call context.getString later in the UI. This approach reduces dependencies and is generally preferable, unless you specifically need to apply logic directly to the string values.

As for your question where should this go?: It belongs in a shared UI module. For example, you could create a product-stocks-ui module and then import it in both plp-ui and cart-ui.

If you anticipate sharing more UI elements, consider naming the module something broader like product-shared-ui. The key point is that whatever you place in this shared module should always be reused together, in line with the Common Reuse Principle. In other words, avoid lumping together classes or functions that will be reused independently. If that’s the case, split them into multiple smaller shared UI modules to prevent unnecessary coupling.

Hope this helps!

DenisBronx avatar Oct 03 '25 10:10 DenisBronx

thanks for your response !!

h2yiwei avatar Oct 09 '25 03:10 h2yiwei