在类或对象中编写算法有什么缺点(在Scala中)?

Joh*_*ood 4 algorithm scala class object

class A {
  def algorithmImplementation (...) = { ... }
}

object A {
  def algorithmImplementation (...) = { ... }
}
Run Code Online (Sandbox Code Playgroud)

应该class使用哪种情况以及应该使用哪种情况object(用于实现算法,例如Dijkstra-Algorithm,如上所示)?

做出这样的决定时应该考虑哪些标准?

目前,我无法真正看到使用a的好处是什么class.

Chr*_*aki 6

如果您只有一个实现,这可能主要是判断调用.你提到了Dijkstra的算法,该算法在图表上运行.现在,您可以编写该算法,将图形对象作为显式参数.在这种情况下,算法可能会出现在Graph singleton对象中.然后它可能被称为Graph.shortestPath(myGraph,fromNode,toNode).

或者您可以在Graph类中编写算法,在这种情况下,它不再将图形作为显式参数.现在它被称为myGraph.shortestPath(fromNode,toNode).

当存在一个主要参数(例如,图形)时,后一种情况可能更有意义,尤其是作为算法的一种上下文的一种.但它可能归结为您喜欢的语法.

但是,如果您有多个实现,那么平衡会更多地提示类方法,尤其是当选择哪个实现更好时,取决于表示的选择.例如,您可能有两个不同的shortestPath实现,一个在邻接矩阵上工作得更好,另一个在邻接列表上工作得更好.使用类方法,您可以轻松地为两个不同的表示形式提供两个不同的图表类,每个图表类都可以拥有自己的shortestPath实现.然后,当您调用myGraph.shortestPath(fromNode,toNode)时,即使您不知道myGraph是否使用邻接矩阵或邻接列表,您也会自动获得正确的实现.(这是OO的重点.)


Jam*_*Iry 5

类可以具有覆盖实现的子类,对象不能被子类化.类也可以是对象不能的类型参数.

这个对象只有一个实例,或者每个容器至少有一个实例.一个类有多个实例.这意味着可以使用值对类进行参数化

class A(param1 : int, param2 : int) {
    def algorithmImplementation(arg : List[String]) = // use arg and params
}
Run Code Online (Sandbox Code Playgroud)

这可以重复使用

val A42_13 = new A(42, 13)
val result1 = A42_13.algorithmImplementation(List("hello", "world"))
val result2 = A42_13.algorithmImplementation(List("goodbye", "cruel", "world"))
Run Code Online (Sandbox Code Playgroud)

相对于你的Djikstra算法的例子,把所有这些带回家:想象你想要编写一个可以在多个节点类型之间重用的算法实现.然后,您可能希望按节点类型,用于测量距离的度量标准类型以及用于计算距离的函数进行参数化.

val Djikstra[Node, Metric <: Comparable[Metric]](distance : (Node, Node) => Metric) {
    def compute(node : Node, nodes : Seq[Node]) : Seq[Metric] = {...}
}
Run Code Online (Sandbox Code Playgroud)

您可以在程序中使用不同类型的节点/度量/距离函数创建一个Djikstra实例,并重复使用该实例,而无需在每次计算Djikstra时传递所有信息.

总之,课程更灵活.在需要灵活性时使用它们.否则对象很好.