Scala Foundation Course - How to implement Factory Pattern in Scala


Welcome back. In the earlier lesson, I promised to talk about Implementing Factory Method in Scala. Let's talk about the Factory Method pattern.

What is Factory Method Pattern?

The factory method is used to offer a single interface to instantiate one of the multiple classes. Well, it doesn't make much sense without an example. So, let's try to understand it with an example. Assume that you are creating a library for a hotel booking application. The library is supposed to give three choices of room types.

  1. Standard
  2. Deluxe
  3. Super Deluxe

You are following an object-oriented design, and hence you decided to create three different classes. One for each room type. Right? You also want to provide methods to get booking price, list of facilities, and the availability. All those three classes will implement their methods individually. Since you are creating a library, you want to keep it simple for your programmers. So, you decided to give them a simple method to create a room object.
You wanted them to be able to create rooms using a single method. Here is an example of how you want them to create a room.

                                
    val s  = Room(STANDARD)
    val d  = Room(DELUXE)
    val sd = Room(SUPER_DELUXE)                                     
                            

The first statement returns an instance of a standard room. The second statement returns a deluxe room, and the third one gives a super deluxe room. You are offering one single method to create a variety of objects. The method room is a factory of rooms. You can make whatever type of room and as many as you want.
This type of object creation is easy to adapt for your programmers. They don't need to worry about different classes for different room types. They can simply create the desired object using a simple method. Isn't it? That's what a factory method is all about. The method Room is a factory of creating different types of rooms. All you need to do is to tell the room type. That's it.

Factory Method Example in Scala

Let's look at the complete code to enable this factory method.

                                            
    //File Name - hotels.scala

    package guru.learningjournal.hotels

    abstract class Room{
        def bookingPrice : Double
        def facilities : List[String]
        def availability : Int
        def book(noOfRooms:Int)
    }

    object Room{
        val STANDARD = 0
        val DELUXE = 1
        val SUPER_DELUXE = 2

        private class standardRoom extends Room{
            private var _availability = 20
            override def bookingPrice = 70
            override def facilities = List("Queen Bed", "TV", "Chair", "Table","Fan")
            override def availability = _availability
            override def book(noOfRooms:Int) = {
                _availability = _availability - noOfRooms
            }
        }

        private class DeluxeRoom extends Room{
            private var _availability = 10
            override def bookingPrice = 90
            override def facilities = List("Bed", "TV", "Chair", "Table","AC")
            override def availability = _availability
            override def book(noOfRooms:Int) = {
                _availability = _availability - noOfRooms
            }
        }

        private class superDeluxeRoom extends Room{
            private var _availability = 5
            override def bookingPrice = 120
            override def facilities = List("Double Bed","Single Bed", "TV", "Sofa", "Reading Table","AC")
            override def availability = _availability
            override def book(noOfRooms:Int) = {
                _availability = _availability - noOfRooms
            }
        }

        def apply(roomType:Int):Room = {
            roomType match {
                case SUPER_DELUXE => new superDeluxeRoom()
                case DELUXE => new DeluxeRoom()
                case _ => new standardRoom()
            }
        }
    }                                            
                                

The first line is declaring a package. The package declaration will allow me to import the class names and static members. Once imported, I can use them without specifying a long prefix. I will cover more on the Scala packages in a separate video.
The next part of the code is an abstract class for the room. We also have four abstract methods. So, my class is done. But since it's an abstract class, no one can instantiate it. Next part is a companion object for the class. We keep the same name and place both into the same source file.The code for the object is simple. I declare three static values. We will use these constants to tell the room type.Then we create three private classes. One for each room type. All these classes are extending the abstract class for the room. We implement those abstract methods for all these private classes.
Finally, I create the apply method. The apply method instantiates the appropriate private class depending upon the input parameter. That's it. This code will allow us to use the room object as a factory method.

How to compile Scala source file

Let's test this code. We have been working over REPL. However, I want to keep this code in a source file and compile it using SBT. The process is simple, and I have already covered it in the first section of this training. Follow these steps.

  1. Create a project directory.
                                    
    mkdir DemoHotel
    cd DemoHotel                                        
                                
  1. Create a Scala source file and place the code in the file.
                                        
    vi hotels.scala                                        
                                    
  1. If you have some dependencies, define them in your build file. That's it.
                                            
    vi build.sbt
    //paste below code in the build.sbt file
    name:= "Demo Hotels"
    version := "1.0"
    scalaVersion := "2.12.4"                                        
                                        

  1. You can compile your class using SBT compile command.

However, you can't execute this program. Why?
Well, we need a main method to execute it as an application. Right?
My code doesn't have a main method. Scala doesn't know where to start the execution. So, we cannot run it as an independent application. However, you can start REPL and test your code.

How to execute Scala code from REPL

Let’s start SBT console and test our code. Follow these steps.

  1. Import the definitions.
                                                
    import guru.learningjournal.hotels.Room
    import guru.learningjournal.hotels.Room._                                       
                                            
  1. Create a room object.
                                                    
    val s = Room(STANDARD)                                      
                                                
  1. Check the price and availability.
                                
    s.bookingPrice
    s.availability                                      
                                                    

Great! But the code that we wrote is not an application. To make it an application, we need to define the main method. I don't want to mix in two separate concepts in a single video, so I will cover that in the next video.
Thank you very much for watching Learning Journal. Keep learning and keep growing.


You will also like:


Kafka Core Concepts

Learn Apache Kafka core concepts and build a solid foundation on Apache Kafka.

Learning Journal

Hadoop Security

Hadoop security implementation using Kerberos.

Learning Journal

Free virtual machines

Get upto six free VMs in Google Cloud and learn Bigdata.

Learning Journal

Lazy Evaluations

Evaluate the expression now vs evaluate it for the first use. Strict vs Lazy?

Learning Journal

Scala named arguments

Learn about named arguments and default values in Scala functions with examples.

Learning Journal