I have covered the visitor pattern explanation in the previous article here is the link for the same scala-visitor-pattern
The visitor design pattern could be represented in a way that is less verbose and closer to Scala using the case classes and pattern matching. Instead of having multiple different visit methods in the Visitor trait we will just have one method which takes a communication provider interface and using pattern matching capability of scala we will run the required algorithm.
Lets code the required interfaces first
trait CommunicationProvider { val pattern = java.util.regex.Pattern.compile("") def accept(visitor: VisitorScalaWay1) }
trait VisitorScalaWay1 { def sendFiles(cp: CommunicationProvider) }
Lets add the concrete visitor implementation DynamicLineDataVisitor and the SystemDataVisitor
import scala.collection.mutable.ListBuffer class DynamicLineDataVisitorScalaWay1(var list: ListBuffer[java.io.File]) extends VisitorScalaWay1 { def sendFiles(cp: CommunicationProvider) = { val pattern = cp.pattern cp match { case Airtel() => { list.foreach { file => if (pattern.matcher(file.getName()).matches()) { println("sending file into "+cp.getClass.getName) } } } case Vadafone() => { list.foreach { file => if (pattern.matcher(file.getName()).matches()) { println("sending file into "+cp.getClass.getName) } } } case Idea() => { list.foreach { file => if (pattern.matcher(file.getName()).matches()) { println("sending file into "+cp.getClass.getName) } } } } } }
import scala.collection.mutable.ListBuffer class SystemDataVisitorScalaWay1(var list: ListBuffer[java.io.File]) extends VisitorScalaWay1 { def sendFiles(cp: CommunicationProvider) = { val pattern = cp.pattern cp match { case Airtel() => { list.foreach { file => if (pattern.matcher(file.getName()).matches()) { println("sending file into "+cp.getClass.getName) } } } case Vadafone() => { list.foreach { file => if (pattern.matcher(file.getName()).matches()) { println("sending file into "+cp.getClass.getName) } } } case Idea() => { list.foreach { file => if (pattern.matcher(file.getName()).matches()) { println("sending file into "+cp.getClass.getName) } } } } } }
Lets add the concrete communication provider implementation
case class Airtel() extends CommunicationProvider { override val pattern:java.util.regex.Pattern = java.util.regex.Pattern.compile("Airtel_(.*).tar.gz"); def accept(visitor: VisitorScalaWay1) = { visitor.sendFiles(this) } }
case class Idea() extends CommunicationProvider { override val pattern:java.util.regex.Pattern = java.util.regex.Pattern.compile("Idea_(.*).tar.gz"); def accept(visitor: VisitorScalaWay1) = { visitor.sendFiles(this) } }
case class Vadafone() extends CommunicationProvider { override val pattern: java.util.regex.Pattern = java.util.regex.Pattern.compile("Vadafone_(.*).tar.gz"); def accept(visitor: VisitorScalaWay1) = { visitor.sendFiles(this) } }
Finally lets code the test class
object Test extends App { import java.io.File import scala.collection.mutable.ListBuffer val file1: File = new File("Airtel_(.*).tar.gz") val file2: File = new File("Vadafone_(.*).tar.gz") val file3: File = new File("Idea_(.*).tar.gz") val listOfFiles = ListBuffer[File](); listOfFiles += file1 listOfFiles += file2 listOfFiles += file3 val dynamicLineDataVisitor = new DynamicLineDataVisitorScalaWay1(listOfFiles); val systemDataVisitor = new SystemDataVisitorScalaWay1(listOfFiles); val airtel = new Airtel(); val vadofone = new Vadafone(); val idea = new Idea(); airtel.accept(dynamicLineDataVisitor); vadofone.accept(systemDataVisitor); idea.accept(dynamicLineDataVisitor); }