Careeroza
Real World Example
Payment Methods at Checkout
Paytm, PhonePe and Amazon accept UPI, cards and wallets. Checkout depends on a PaymentMethod interface, so adding a new method (e.g. Pay Later) does not change the checkout code.
Example
interface PaymentMethod {
val displayName: String
fun pay(amount: Double): Boolean
fun fee(amount: Double): Double = 0.0 // default: free
}
class Upi(private val vpa: String) : PaymentMethod {
override val displayName = "UPI ($vpa)"
override fun pay(amount: Double) = amount <= 100000
}
class Card(private val last4: String) : PaymentMethod {
override val displayName = "Card **** $last4"
override fun pay(amount: Double) = true
override fun fee(amount: Double) = amount * 0.02
}
class Wallet(private var balance: Double) : PaymentMethod {
override val displayName = "Wallet"
override fun pay(amount: Double): Boolean {
if (amount > balance) return false
balance -= amount
return true
}
}
fun checkout(amount: Double, method: PaymentMethod) {
val total = amount + method.fee(amount)
val ok = method.pay(total)
println("%-18s total %8.2f -> %s".format(method.displayName, total, if (ok) "SUCCESS" else "FAILED"))
}
fun main() {
checkout(1200.0, Upi("asha@okicici"))
checkout(1200.0, Card("4242"))
checkout(1200.0, Wallet(500.0))
}Output
UPI (asha@okicici) total 1200.00 -> SUCCESS Card **** 4242 total 1224.00 -> SUCCESS Wallet total 1200.00 -> FAILED
Android: Repository Interface
In Android apps the ViewModel depends on an interface, not a concrete class. The real implementation calls Retrofit/Room; a fake one is used in tests.
interface ProductRepository {
suspend fun getProducts(): List<Product>
}
class NetworkProductRepository(private val api: ShopApi) : ProductRepository {
override suspend fun getProducts() = api.fetchProducts()
}
class FakeProductRepository : ProductRepository {
override suspend fun getProducts() = listOf(Product(1, "Test Phone", 9999.0))
}
class ProductViewModel(private val repo: ProductRepository) : ViewModel()