The Factory Pattern in Scala
The factory method is used to offer a single interface to instantiate one of the multiple classes. In the Factory pattern, the objective is to make the object in such a way that it does not expose to the creation logic to the Client and can always refer to a newly created object with the help of a common interface.
Let’s try to understand it with an example.
Assume that we need to create a library for a Car Purchase Application. The library is supposed to give three choices of cars types.
- Standard
- Deluxe
- Luxury
We are following an object-oriented design, and hence we decided to create three different classes. One for each car type. We also want to provide methods to get the booking price, Brands, and availability. All three classes will implement their methods individually but we have to decide on a simple method to create a Car object. So that all the cars can be purchased using the same method. Here is an example of how we want to book a car. the first statement returns an instance of a Standard car. the second statement returns a Deluxe Car, and the third one gives a Luxury Car. we are in this case offering one single method to create a variety of objects. the method Car here is a factory of Cars. we can book whatever type of car we need and as many as we want. this type of object creation makes programming very easy and the codes compact. one need not worry about different classes for different kinds of cars. That’s what a factory method is all about.
// Scala program of Design factory pattern // creating abstract class for the car abstract class Car{ // Creating four abstract methods def bookingPrice : Double def Brands : List[String] def availability : Int def book(noOfCars : Int) } // Creating an object object Car{ val STANDARD = 0 val DELUXE = 1 val LUXURY = 2 // Creating private class private class standardCar extends Car{ private var _ availability = 100 override def bookingPrice = 200000 override def Brands = List( "Maruti" , "Tata" , "Hyundai" ) override def availability = _ availability override def book(noOfCars : Int) = { _ availability = _ availability - noOfCars } } // Creating private class private class DeluxeCar extends Car{ private var _ availability = 50 override def bookingPrice = 500000 override def Brands = List( "Honda" , "Mahindra" , "Chevrolet" ) override def availability = _ availability override def book(noOfCars : Int) = { _ availability = _ availability - noOfCars } } // Creating private class private class LuxuryCar extends Car{ private var _ availability = 5 override def bookingPrice = 900000 override def Brands = List( "Audi" , "BMW" , "Mercedes" ) override def availability = _ availability override def book(noOfCars : Int) = { _ availability = _ availability - noOfCars } } // create the apply method // single method to create a variety of objects def apply(carType : Int) : Car = { carType match { case LUXURY => new LuxuryCar() case DELUXE => new DeluxeCar() case STANDARD => new standardCar() case _ => new standardCar() } } // Main method def main(args : Array[String]) { val s = Car(STANDARD) println(s.bookingPrice) println(s.availability) } } |
Output:
200000.0 100
The factory method thus helps a lot in making programming concepts easier. In this way, we can always save the codespace and the number of classes if declaring multiple objects of same type with some dissimilarities.