Factory Design Pattern là một trong những Creational Design Pattern phổ biến nhất.
Mục đích chính của Factory Design Pattern là logic tạo các instance và object riêng biệt từ client. Chúng ta thực thi logic tạo ra object trong Factory class mà không để lộ logic đó cho phía Client.
Factory Design Pattern cũng được biết như là Factory Method Design Pattern. Nó thường được sử dụng khi chúng ta có một supper class với nhiều class con và dựa vào đầu vào, chúng ta cần trả về một trong những class con.
Ưu điểm của Factory Design Pattern
Factory Design Pattern có những ưu điểm sau:
- Kết nối tách rời giữa logic tạo object và client
- Phân tách rõ ràng trách nhiệm
- Dễ dàng thay đổi logic tạo object không gây ảnh hưởng đến chương trình client
Factory Design Pattern trong Scala
Trong Scala chúng ta có thể thực hiện một Factort class sử dụng Singleton object và pattern matching.
Đầu tiên chúng ta sẽ tạo class kế thừa và Factory class như bên dưới
ComputerFactory.scala
package com.journaldev.designpattern.factory trait Computer{ def getRAM():String def getHDD():String def getCPU():String override def toString = "RAM= " + getRAM +", HDD=" + getHDD + ", CPU=" + getCPU } private class PC(val ram:String, val hdd:String, val cpu:String) extends Computer{ def getRAM():String = ram def getHDD():String = hdd def getCPU():String = cpu } private class Server(val ram:String, val hdd:String, val cpu:String) extends Computer{ def getRAM():String = ram def getHDD():String = hdd def getCPU():String = cpu } object ComputerFactory{ def apply(compType:String, ram:String, hdd:String, cpu:String) = compType.toUpperCase match { case "PC" => new PC(ram,hdd,cpu) case "SERVER" => new Server(ram,hdd,cpu) } }
Scala không có khái niệm interface. Tuy nhiên, nó có khái niệm mạnh hơn interface đó là: Trait. Ở trên, chúng ta đã code dựa trên Trait với tất cả các hàm và phương thức cần thiết.
Object ComputerFactory
là một Singleton Object. Nó được sử dụng để cung cấp phương thức factory để tạo object của chúng ta. Tiếp theo tạo một client để test đoạn code Scala này:
FactoryMethodDesignPatternClient.scala
object FactoryMethodDesignPatternClient extends App{ val pc = ComputerFactory("pc","2 GB","500 GB","2.4 GHz"); val server = ComputerFactory("server","16 GB","1 TB","2.9 GHz"); println("Factory PC Config::"+pc); println("Factory Server Config::"+server); }
Output
Factory PC Config::RAM= 2 GB, HDD=500 GB, CPU=2.4 GHz Factory Server Config::RAM= 16 GB, HDD=1 TB, CPU=2.9 GHz
Cải tiến Factory Design Pattern trong Scala
Trong phần này chúng ta sẽ thử cải tiến đoạn code bên trên sử dụng case class của Scala.
package com.journaldev.designpattern.factory trait Computer{ def ram:String def hdd:String def cpu:String override def toString = "RAM= " + ram +", HDD=" + hdd + ", CPU=" + cpu } private case class PC(ram:String, hdd:String, cpu:String) extends Computer private case class Server(ram:String, hdd:String, cpu:String) extends Computer object ComputerFactory{ def apply(compType:String, ram:String, hdd:String, cpu:String) = compType.toUpperCase match { case "PC" => PC(ram,hdd,cpu) case "SERVER" => Server(ram,hdd,cpu) } }
Sử dụng đoạn code Client ở trên để test thì chúng ta sẽ nhận được kết quả tương tự.