具有功能样式编程的链接对象?

时间:2012-06-05 23:02:21

标签: design-patterns scala

我是Scala的新手,但他是一位经验丰富的程序员,他试图摆脱旧习惯并加入功能风格。我正在设计的一个简单程序涉及问题/答案对象,并保留一些关于成功的基本事实。仅使用不可变对象就足够了 - 但我的目标之一是链接相关事实,因此程序可能会偶尔询问它们。 (例如:“骑士骑士车是谁?”,“什么电视节目以黑斑羚为特色?”

在Java中我可能刚刚链接了相关的对象,就像我在下面写的那样,但是不可变的法则阻止了这一点(我无法链接A-> B并实例化B - > A除非我一次性完成它? )

我必须承认,这可能是一件好事 - 也许功能风格旨在阻止这种循环引用。但我不知道如何纠正这个问题。一旦提出问题,我的设计就会失败 - 因为这会返回一个复制对象,其值为“right,ask”,因此对象链接似乎又是一个陷阱。我最好的猜测是在辅助对象中构建关系集,仅基于Q / A数据,但我想避免使用单独的数据模式对象。

谢谢大家 - 俄亥俄州哥伦布市的蒂姆

case class FactItem (

    q:String, a:String,
    right: Double = 0.0,
    asked: Double = 0.0,
    linked: List[FactItem] = List[FactItem]()

    ) { 

  def rP = right / asked //right per

  def subLink( l:List[FactItem] ) : FactItem =  {
    this.copy( linked = l-this)

  } 

2 个答案:

答案 0 :(得分:2)

有关如何以不可变的方式执行此操作,请参阅此问题:scala: how to model a basic parent-child relation

提示:不要在案例类中执行此操作,除非您覆盖toString以不包括项目列表(如果存在循环引用,您将溢出堆栈,因为此项目的toString包括列表中所有其他人的toString。

通过使List成为private var并在引用列表项后,在创建所有项目的伴随对象中更新工厂方法中的所有实例,可以节省很多麻烦。没有公共制定者,它仍然是有效的不可改变的。

类似的,理论上更合理的方法是使列表成为Stream,从伴侣对象的地图中获取其值。

表示,在创建项目时,地图必须是可变的,但至少这些项目是完全不可变的。

答案 1 :(得分:2)

真正的答案是不要那样做。创建一个指向两者的“Relation”对象。

现在你可能想知道你是如何从一个指向“关系”的对象转变为“关系”本身然后是另一个对象,你是通过使用拉链来实现的。您可以获得树/图,而不是直接转到对象“a”,而拉链移动到“a”。从那里,如果拉链知道横向移动,您可以返回“关系”并转发到“b”,或直接从“a”转到“b”。

不幸的是,当谈到有用的拉链时,Scala远远落后于Haskell。但是如果你理解了这个概念(我将让你去研究),你总是可以为你的数据结构创建一个。

还有另一个可能适用的答案。你可能有一个“镜头”,它是一个知道如何分开并整理(修改)其他物体的对象。该课程的基本设计必须允许它(具有可变性或懒惰技巧),但镜片隐藏了操作本身的丑陋(除了提供许多其他漂亮的功能)。

最后,我想强调的是,Scala完全没有 纯粹的功能:Odersky认为纯函数式语言之外的价值,并希望你有这种能力。