Visitor pattern in Scala

访问者模式在《Design Patterns: Elements of Reusable Object-Oriented Software》的定义如下:

Represent an operation to be performed on the elements of an object structure.Visitor lets you define a new operation without changing the classes of the elements on which it operates.

对于访问者模式的优缺点或者代码样例可以参考电子工业出版社的《Java 与模式》和清华大学出版社的《Java设计模式》

下面将重点介绍在函数式编程中如何实现访问者模式
在不改变原有类的情况下增加新的操作,这里用到了scala中的隐式类,指的是用implicit关键字修饰的类。

  • 下面的样例中,在不改变SimplePerson类的前提下,想增加一个操作fullAddress,只要增加一个implicit class ExtendedPerson类,那么就可以直接调用simplePerson.fullAddress,这里操作的是SimplePerson中的houseNum和street属性
  • 虽然ComplexPerson 和SimplePerson 实现方式不同,但是implicit class ExtendedPerson同样适用
object VisitorPattern {
  trait Person {
    def fullName: String
    def firstName: String
    def lastName: String
    def houseNum: Int
    def street: String
  }

  class SimplePerson(val firstName: String, val lastName: String,
                     val houseNum: Int, val street: String) extends Person {
    def fullName = firstName + " " + lastName
  }

  implicit class ExtendedPerson(person: Person) {
    def fullAddress = person.houseNum + " " + person.street
  }

  class ComplexPerson(name: Name, address: Address) extends Person {
    def fullName = name.firstName + " " + name.lastName

    def firstName = name.firstName
    def lastName = name.lastName
    def houseNum = address.houseNum
    def street = address.street
  }
  class Address(val houseNum: Int, val street: String)
  class Name(val firstName: String, val lastName: String)

  def main(args: Array[String]): Unit = {
    val simplePerson = new SimplePerson("Mike", "Linn", 123, "Fake. St.")
    println(simplePerson.fullName)
    println(simplePerson.fullAddress)


    val name = new Name("Tom", "Linn")
    val address = new Address(456, "Fake St.")
    val complexPerson = new ComplexPerson(name, address)
    println(complexPerson.fullName)
    println(complexPerson.fullAddress)
  }
}

输出结果为

Mike Linn
123 Fake. St.
Tom Linn
456 Fake St.

返回目录

你可能感兴趣的:(Visitor pattern in Scala)