Scala: Implementing Factory

In a previous post we explained the Design Pattern Factory Method and how it differs from the Builder Pattern. Now we will explain how to implement this pattern in Scala. However, first we need to learn a new concept in Scala: the Companion Objects.

Companion Object

Previously, we said that a Companion Object could be seen, from a Java point of view, as a Static Class.

A Companion Object is an Object that shares the same name and source file with another Class or Trait. A Trait could be seen as a Java Interface.

The Companion Object is useful for implementing utility methods, factories, apply and unapply methods…

When it does exist a Companion, the class is called Companion Class and the object is called Companion Object. This name’s collision is possible because they don’t share the same namespace. While classes are stored in the type namespace, objects are stored in the term namespace. You can read the Scala language specifications here.

Implementing Queue Factory in Java

We want to implement a factory that produces different types of shapes depending on the number of sides given.
First of all, we need the abstract class. In this example it could be an interface, but we could also add some other common properties as fill colour, line colour…

package com.wordpress.j2eethoughts.factory; public abstract class Shape { public abstract double getArea(); public abstract double getPerimeter(); }

We will work with two different kinds of shapes: triangle and rectangle. Here comes the code for Triangle:

package com.wordpress.j2eethoughts.factory; public class Triangle extends Shape { private double ab; private double bc; private double ac; public Triangle(double ab, double bc, double ac) { super(); this.ab = ab; this.bc = bc; this.ac = ac; } @Override /** * Heron's way */ public double getArea() { double s = getPerimeter()/2; return Math.sqrt(s*(s-ac)*(s-ab)*(s-bc)); } @Override public double getPerimeter() { return ab+bc+ac; } }

And this is the source for Rectangle:

package com.wordpress.j2eethoughts.factory; public class Rectangle extends Shape { private double height; private double length; public Rectangle(double height, double length){ super(); this.height = height; this.length = length; } @Override public double getArea() { return height*length; } @Override public double getPerimeter() { return (height*2)+(length*2); } }

And finally, the source of the factory:

package com.wordpress.j2eethoughts.factory; public class ShapeFactory { public static Shape getShape(double len1, double len2, double len3){ return new Triangle(len1,len2,len3); } public static Shape getShape(double len1, double len2){ return new Rectangle(len1,len2); } }

After this, we can test this classes with this little application:

package com.wordpress.j2eethoughts.factory; public class Main { public static void main(String[] args) { Shape sh1 = ShapeFactory.getShape(32.34, 23); System.out.println(sh1.getArea()); System.out.println(sh1.getPerimeter()); Shape sh2 = ShapeFactory.getShape(5, 3, 4); System.out.println(sh2.getArea()); System.out.println(sh2.getPerimeter()); } }

Implementing Queue Factory in Scala

If we want to implement this shape factory in Scala we will need only one source file. We will use a companion class Shape and a companion object Shape, this last one will act as a factory. Therefore, the concrete implementations of Shape will be private classes of the companion object. With this approach, we hide any concrete implementation of Shape from the client.

This is the source code for the companion class and object.

package com.wordpress.j2eethoughts.queue import scala.Math.sqrt abstract class Shape { def perimeter : Double def area : Double } object Shape { private class Triangle (ab : Double, bc : Double, ac : Double) extends Shape{ override val perimeter = ab + bc + ac private val s = perimeter / 2 override val area = sqrt(s*(s-ac)*(s-ab)*(s-bc)) } private class Rectangle (height : Double, length : Double) extends Shape{ override val perimeter = height * 2 + length * 2 override val area = height * length } def apply(ab : Double, bc : Double, ac : Double) : Shape = new Triangle(ab,bc,ac) def apply(height : Double, length : Double) : Shape = new Rectangle(height,length) }

I would like to make some considerations about this implementation. When we override a method, the keyword override is mandatory, it won’t compile if it’s not included. Furthermore, it’s possible to override a method with a variable. If you look at the concrete classes, the abstract methods defined in Shape are overridden with a val.

Now we will test the Shape Factory:

package com.wordpress.j2eethoughts.queue object Main { def main(args : Array[String]) : Unit = { val sh1 = Shape (32.34, 23) println(sh1.area) println(sh1.perimeter) val sh2 = Shape (3,4,5) println(sh2.area) println(sh2.perimeter) } }
Advertisements