By Alvin Alexander. Last updated: May 18, 2022
Here’s a small example of how to create a Factory Pattern in Scala. In the Scala Cookbook I created what some people might call a simple factory and/or static factory, so the following code is a much better implementation of a true OOP Factory Pattern.
My Scala factory classes
I don’t have too much time to explain the code today, but here are the classes that make up my Scala factory, including a set of “animal” classes along with a DogFactory
and CatFactory
that extend an AnimalFactory
trait:
package animals {
// --------------
// Animal classes
// --------------
sealed trait Animal {
def speak: Unit
}
sealed trait Dog extends Animal
private class LittleDog extends Dog { def speak = println("arf") }
private class GenericDog extends Dog { def speak = println("woof") }
private class BigDog extends Dog { def speak = println("WOOF!") }
sealed trait Cat extends Animal
private class GenericCat extends Cat { def speak = println("meow") }
private class GrumpyCat extends Cat { def speak = println(":(") }
private class SmellyCat extends Cat { def speak = println("..oOo..") }
// ---------------------
// AnimalFactory classes
// ---------------------
trait AnimalFactory {
def getAnimal(criteria: String): Animal
}
class DogFactory extends AnimalFactory {
def getAnimal(criteria: String): Animal = criteria match {
case "small" | "little" => new LittleDog
case "big" | "large" => new BigDog
case _ => new GenericDog
}
}
class CatFactory extends AnimalFactory {
def getAnimal(criteria: String) = criteria match {
case "smells" | "smelly" => new SmellyCat
case "grumpy" => new GrumpyCat
case _ => new GenericCat
}
}
}
Note that unlike what I did in the Cookbook, I don’t use object
here; everything is implemented with traits and classes.
Testing the factory
Next, here’s an App
I used to test the factory, including making sure I could access all of the concrete Dog
and Cat
classes:
/**
* i put this code in another package to confirm that i can
* use the Dog and Cat classes.
*/
package factory_pattern {
import animals._
object FactoryPattern extends App {
val dogFactory: AnimalFactory = new DogFactory
val catFactory: AnimalFactory = new CatFactory
println("=== SOME DOGS ===")
val smallDog = dogFactory.getAnimal("small")
val bigDog = dogFactory.getAnimal("big")
val dog = dogFactory.getAnimal("other")
smallDog.speak
bigDog.speak
dog.speak
println("=== SOME CATS ===")
(catFactory.getAnimal("smells")).speak
(catFactory.getAnimal("grumpy")).speak
(catFactory.getAnimal("regular")).speak
}
}