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

4 Responses

  1. Mr Josep Lluis, you surprise me every day. And you have shown me that you’re a great friend. Thanks!

  2. […] This post was mentioned on Twitter by Richard Laksana, scopedog. scopedog said: Scala: Implementing Factory « All-Code-Edges: Java, Scala and Design Patterns http://htn.to/nMTewK […]

  3. Hi,
    You can change those “def elem” functions to “def apply”, and get a little more brief and “idiomatic”:

    scala> Shape(1,2,3)
    res0: Shape = Shape$Triangle@7c2f5dda

    scala> Shape(1,2)
    res1: Shape = Shape$Rectangle@7d8aecf1

    This is how Scala collection initializers work. Thanks for blogging!

  4. Thanks for the hint Adam,
    I have updated the post.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: