【问题标题】:Scala - implementing "manager" pattern in companion object?Scala - 在伴生对象中实现“管理器”模式?
【发布时间】:2012-05-03 18:24:14
【问题描述】:

当我使用 Java 编程时,我曾经有对象和管理器。你知道,一个类(通常是单例),它将保存某个类的对象的集合,并可以方便地管理它们。现在,在 Scala 中,我发现自己越来越处于这种情况下,将所有功能放在伴随对象中并避免创建不同的管理器对象是很诱人的。

这一切都始于为实例提供 ID,然后......为什么不在伴随对象中包含集合?如果集合在那里,为什么不把所有的方法都放在里面呢?因此,不再需要经理。然而,一个特点是伴随对象通常只有一个名称,如Car(不像CarsCarManager 假定多个),因此使用复数操作的方法在与对象名称的耦合措辞中看起来很奇怪。

我想知道您对这种情况的看法,并想知道这种方法是否比看似不必要的臃肿经理模式更可取。对任何文章的任何引用也将不胜感激。

【问题讨论】:

  • 嗯...不太清楚这与问题有何关系,但无论如何谢谢,我会去阅读它! (ScalaTodoList 教程除外,因为我早就通过了)。
  • 他们使用伴随对象来保存所有模型操作。如果我理解正确,您也可以尝试这样做。
  • 哦,先没认出来。 Play 框架是一个不同的例子,但是对于 Salat,他们似乎真的在实践一种类似于我所询问的方法。他们将它与 thoredge 的建议混合在一起——依赖注入!

标签: scala design-patterns


【解决方案1】:

越简单越好;对象内部的集合确实很简单。但是,您还应该避免使您的对象依赖于静态对象。这将创建一个僵化的结构,并使测试更加困难。

我会看一下蛋糕图案(请参阅How do you do dependency injection with the Cake pattern without hardcoding?)。这样,您可以将 CarManager 放在一个对象中,并通过 CarRepositoryComponent 将其混合到您的依赖项中。

非编译示例:

val someService = new SomeService 
  with MyRepairServiceComponent with CarCollectionRepositoryComponent
someService.repairCar(8)

trait SomeService extends RepairServiceComponent with CarRepositoryComponent {
  def repairCar(id: Int): Status = repairService.repair(carRepository.get(id));
}

trait CarRepository {
  abstract def get(id: Int): Car
}
trait CarRepositoryComponent {
  abstract def carRepository: CarRepository
} 

object CarManager extends CarRepository {
  private var cars = Map[Int, Car]()
  def get(id: Int): Car = cars(id)
}
trait CarCollectionRepositoryComponent {
  def carRepository = CarManager
}

【讨论】:

    【解决方案2】:

    这实际上是把一个伴生对象变成了一个单例,这更像是一种反模式,而不是一种好的设计模式。单元测试是造成这个问题的主要原因(这已经被许多比我聪明的人多次讨论过)。

    由于这些原因,一个对象理想地不应该保持任何类型的可变状态(相信我,这会导致维护噩梦)。

    【讨论】:

    • 嗯,我没有使用单元测试,也不会很快使用......而且我必须使用很多可变状态,因为我编写资源要求高且时间关键的应用程序......所以我明白什么你是说,但看起来你是从与我的正交经验说的:D.. 由于我不完全遵守函数式编程,我将不得不将可变状态单项放在某个地方。不同之处在于 - 它是否应该是一个单独的对象。如果这是一个糟糕的设计,并且有办法以另一种方式实现相同的生产力,我会很高兴听到如何。
    • 我认为将不良工具限制归咎于代码并不是一件特别好的事情。 Scalamock 可以模拟对象。
    • 拥有一个用于管理实例的类不是反模式,单例模式才是。
    猜你喜欢
    • 2015-08-12
    • 1970-01-01
    • 2010-10-11
    • 1970-01-01
    • 2012-04-05
    • 1970-01-01
    • 2016-05-23
    • 2014-10-24
    • 2015-08-26
    相关资源
    最近更新 更多