0

在斯卡拉 - 我们can do扩展方法是这样的:扩展方法,构建器模式和流畅接口之间有什么区别?

object MyExtensions { 
    implicit class RichInt(val i: Int) extends AnyVal { 
    def square = i * i 
    } 
} 

我们可以用这样的:

import MyExtensions._ 
Int i = 2; 
Val squared = i.square() 
Val cubed = i.square().square() 

我们可以do the builder模式是这样的:

sealed abstract class Preparation 
case object Neat extends Preparation 
case object OnTheRocks extends Preparation 
case object WithWater extends Preparation 

sealed abstract class Glass 
case object Short extends Glass 
case object Tall extends Glass 
case object Tulip extends Glass 

case class OrderOfScotch(val brand:String, val mode:Preparation, val isDouble:Boolean, val glass:Option[Glass]) 

class ScotchBuilder { 
    private var theBrand:Option[String] = None 
    private var theMode:Option[Preparation] = None 
    private var theDoubleStatus:Option[Boolean] = None 
    private var theGlass:Option[Glass] = None 

    def withBrand(b:Brand) = {theBrand = Some(b); this} /* returning this to enable method chaining. */ 
    def withMode(p:Preparation) = {theMode = Some(p); this} 
    def isDouble(b:Boolean) = {theDoubleStatus = some(b); this} 
    def withGlass(g:Glass) = {theGlass = Some(g); this} 

    def build() = new OrderOfScotch(theBrand.get, theMode.get, theDoubleStatus.get, theGlass); 
} 



object BuilderPattern { 
    class ScotchBuilder(theBrand:Option[String], theMode:Option[Preparation], theDoubleStatus:Option[Boolean], theGlass:Option[Glass]) { 
    def withBrand(b:String) = new ScotchBuilder(Some(b), theMode, theDoubleStatus, theGlass) 
    def withMode(p:Preparation) = new ScotchBuilder(theBrand, Some(p), theDoubleStatus, theGlass) 
    def isDouble(b:Boolean) = new ScotchBuilder(theBrand, theMode, Some(b), theGlass) 
    def withGlass(g:Glass) = new ScotchBuilder(theBrand, theMode, theDoubleStatus, Some(g)) 

    def build() = new OrderOfScotch(theBrand.get, theMode.get, theDoubleStatus.get, theGlass); 
    } 

    def builder = new ScotchBuilder(None, None, None, None) 
} 

我们可以使用它是这样的:

import BuilderPattern._ 

val order = builder withBrand("Takes") isDouble(true) withGlass(Tall) withMode(OnTheRocks) build() 

我们可以do the fluent界面是这样的:

class Person { 
    protected var fname = "" 
    protected var lname = "" 
    def setFirstName(firstName: String): this.type = { 
     fname = firstName 
     this 
    } 
    def setLastName(lastName: String): this.type = { 
     lname = lastName 
     this 
    } 
} 

class Employee extends Person { 
    protected var role = "" 
    def setRole(role: String): this.type = { 
     this.role = role 
     this 
    } 
    override def toString = { 
     "%s, %s, %s".format(fname, lname, role) 
    } 
} 

我们可以用这样的:

object Main extends App { 
    val employee = new Employee 
    // use the fluent methods 
    employee.setFirstName("Al") 
      .setLastName("Alexander") 
      .setRole("Developer") 
    println(employee) 
} 

所有这三个给出类似的接口,内部DSL。

我的问题是:扩展方法,构建器模式和流畅接口之间有什么区别?

回答

0

这是三个完全分开的概念,它们完成不同的事情。

扩展方法允许您将方法添加到已存在的类中。这可以导致一个更好的API,而不是创建一个将该类的对象作为参数的方法。

构建器模式允许您通过首先在可变对象中设置这些参数来构造一个包含许多选项和参数的对象,然后调用“构建”方法来初始化您正在创建的(通常是不可变的)对象。这很有用,因为它不需要使用许多参数的巨大构造函数,并且在某些参数是可选的缺省值时特别有用。

流畅的API意味着“setter”方法将返回对象本身,而不是返回Unit/void。这允许您可以将方法调用连接在一起的API。例如使用一个虚构Point2D类

val point = new Point2d().setX(3).setY(5) 

使用流利API

val point = new Point2d() 
point.setX(3) 
point.setY(5) 

是未经流利API

相关问题