Advanced Object-Oriented Programming in Kotlin

May 22 2024 · Kotlin 1.9, Android 14, Kotlin Playground

Lesson 04: Liskov Substitution, Interface Segregation & Dependency Inversion

Implementing Liskov Substitution Principle

Episode complete

Play next episode

Next

Heads up... You’re accessing parts of this content for free, with some sections shown as obfuscated text.

Heads up... You’re accessing parts of this content for free, with some sections shown as obfuscated text.

Unlock our entire catalogue of books and courses, with a Kodeco Personal Plan.

Unlock now

In this demo, you’ll redesign your payment processing functionality to include rewards while following the Liskov Substitution principle.

Validating debit card ...
Running fraud checks on debit card ...
Handling debit card payment ...
Saving payment details to database ...

Validating credit card ...
Running fraud checks on credit card ...
Handling credit card payment ...
Saving payment details to database ...
abstract class PaymentMode {
  // Validate the mode of payment
  abstract fun validate()

  // Check for fraud
  abstract fun runFraudChecks()

  // Perform debit transaction to seal payment
  abstract fun handlePayment()
}
internal class CreditCard : PaymentMode() {
  override fun validate() {
    println("Validating credit card ...")
  }

  override fun runFraudChecks() {
    println("Running fraud checks on credit card ...")
  }

  override fun handlePayment() {
    println("Handling credit card payment ...")
  }
}
class PaymentProcessor {
  fun process(orderDetails: OrderDetails, paymentMode: PaymentMode) {
    try {
      paymentMode.validate()
      paymentMode.runFraudChecks()
      paymentMode.handlePayment()
      saveToDatabase(orderDetails, paymentMode)
    } catch (e: Exception) {
      // Exception handling with specific exception type
    }
  }

  private fun saveToDatabase(orderDetails: OrderDetails, paymentMode: PaymentMode) {
    println("Saving payment details to database ...")
  }
}

class OrderDetails {}
interface IPaymentMode {
  fun validate()

  fun handlePayment()
}
class PaymentProcessor {
  fun process(orderDetails: OrderDetails, paymentMode: IPaymentMode) {
    try {
      paymentMode.validate()
      paymentMode.handlePayment()
      saveToDatabase(orderDetails, paymentMode)
    } catch (e: Exception) {
      // Exception handling with specific exception type
    }
  }

  private fun saveToDatabase(orderDetails: OrderDetails, paymentMode: IPaymentMode) {
    println("Saving payment details to database ...")
  }
}
internal abstract class BaseCard : IPaymentMode {
  abstract override fun validate()

  override fun handlePayment(){
    runFraudChecks()
  }

  abstract fun runFraudChecks()
}
internal class CreditCard : BaseCard() {
  override fun validate() {
    println("Validating credit card ...")
  }

  override fun runFraudChecks() {
    println("Running fraud checks on credit card ...")
  }

  override fun handlePayment() {
    super.handlePayment()
    println("Handling credit card payment ...")
  }
}
Validating debit card ...
Running fraud checks on debit card ...
Handling debit card payment ...
Saving payment details to database ...

Validating credit card ...
Running fraud checks on credit card ...
Handling credit card payment ...
Saving payment details to database ...
internal class RewardsCard : IPaymentMode {
  override fun validate() {
    println("Validating rewards card ...")
  }

  override fun handlePayment() {
    println("Handling rewards card payment ...")
  }
}
val rewardsCard = RewardsCard()
paymentProcessor.process(orderDetails, rewardsCard)
Running fraud checks on debit card ...
Handling debit card payment ...
Saving payment details to database ...

Validating credit card ...
Running fraud checks on credit card ...
Handling credit card payment ...
Saving payment details to database ...

Validating rewards card ...
Handling rewards card payment ...
Saving payment details to database ...
See forum comments
Cinema mode Download course materials from Github
Previous: Learning Liskov Substitution Principle Next: Learning Interface Segregation Principle