Advanced Object-Oriented Programming in Kotlin

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

Lesson 02: Design Patterns

Implementing Singleton Pattern

Episode complete

Play next episode

Next
Transcript

There are various techniques to implement the singleton design pattern, but the core concept remains consistent — ensuring that only one instance of an object exists and is accessible throughout the program. In this demo, you’ll use this pattern to create your shopping cart, ensuring you’ll always have precisely one cart for your shopping needs.

Start by opening the Kotlin playground in your browser. Download the course material from the GitHub link at the side of the video. Copy and paste the code from Singleton.kts in the Starter folder for Lesson 2.

The code is similar to what you had in Lesson 1. Here’s a breakdown of the code:

  • Product: This represents a product in the e-commerce app.
  • OrderItem: This represents the product and quantity of an item you wish to purchase.
  • ShoppingCart: This class has a container for keeping your order items.
  • ElectronicsShop: This represents a part of the overall shop where you can purchase electronic items.
  • SportsShop: This represents a part of the overall shop where you can purchase sports items.

Run the app. It shows an empty cart in the output:

- You have 0 order items, at the cost of $0.0

Now, pick up some items from the electronics shop by adding the following code below // TODO: Add items from the electronics shop:

val electronicsShop = ElectronicsShop()
electronicsShop.addItem(electronicsShop.ps5, 1)
electronicsShop.addItem(electronicsShop.xBoxController, 2)

And add a few more from the sports shop by adding the following code below // TODO: Add items from the sports shop:

val sportsShop = SportsShop()
sportsShop.addItem(sportsShop.skatingGloves, 2)
sportsShop.addItem(sportsShop.ankleProtector, 2)

Rerun the app and take note of the results:

- You have 0 order items, at the cost of $0.0

It’s the same as before, even though you’ve added items to the cart. This is because each time you go to the cart, a new instance is created for you. So, you have multiple instances of the cart instead of one where you can easily track all your order items.

For this reason, you’ll change the ShoppingCart implementation to a singleton. Making a class a singleton is easy in Kotlin. You just need to change it from class to object.

First, make ShoppingCart private to prevent creating an instance directly. This forces anyone who needs an instance to use the instance property you’ll create later:

class ShoppingCart private constructor() {

This way, you can’t instantiate ShoppingCart like you used to. Instead, create a companion object that provides an instance of ShoppingCart below // TODO: Create singleton instance:

companion object {
  val instance: ShoppingCart by lazy {
    ShoppingCart()
  }
}

By using the companion keyword, you can access instance using the class name: ShoppingCart. by lazy ensures that instance is evaluated lazily. This means you defer the code execution to when the method is first called. Without this, the code would be executed eagerly. That means it would execute when the class is first loaded into memory when the app starts.

Access to an instance of ShoppingCart is only available via the instance property. Update the code in all the places where you initially used ShoppingCart(). Instead, use ShoppingCart.instance. Find one in ElectronicsShop under // TODO: Instantiate a shopping cart:

private val cart = ShoppingCart.instance

Find another in SportsShop under // TODO: Instantiate a shopping cart:

private val cart = ShoppingCart.instance

And lastly, find one under // Get an instance of the shopping cart in main():

val cart = ShoppingCart.instance

All done. Rerun the app:

- You have 4 order items, at the cost of $874.0

This time, every instance of ShoppingCart is the same, so you’re able to save all your items in the same cart. In the next segment, you’ll learn about the factory pattern.

See forum comments
Cinema mode Download course materials from Github
Previous: Learning Singleton Pattern Next: Learning Factory Pattern