有条不紊地执行一种方法 - 以一种美丽的方式

时间:2013-10-20 19:27:18

标签: scala

假设如下:

  /**
 * the importer trait that glues extractor , transformator and loader together
 * (mini etl)
 */
trait Importer[A, B, C] {

  //this makes sure that the importer 
  //implements an extractor, a transformator and a loader (selfytping)

  self: Extractor[A, B] with Transformator[B, C] with Loader[C] =>

  /**
   * this is the method call for chaining all events together
   */
  def importAndTransformData(dataSource: A): Unit =
    {

      /**
       * perform initializations if necessary
       */
      initializeExtractor
      /**
       * extraction step
       */
      val output = extract(dataSource: A)

      /**
       * before the loading takes place we initialize the Loader if required
       */
      initializeLoader
      /**
       * conversion method that gets injected the load method
       */
      val transformed = transform(output, load)

      /**
       * perform actions afterwards if required
       */
      cleanupExtractor

      cleanupLoader

    }

启动方法目前有一个无效的虚拟实现。 如果需要,由具体的特征/子类覆盖它。 这似乎有点笨拙。

有更好的方法吗?

1 个答案:

答案 0 :(得分:0)

一堂课应该只做一件事而且只做一件事:

  • 提取器应该知道如何提取
  • 变形金刚应该知道如何改造而不是别的
  • 装载者应该知道如何装载而不是其他任何东西
  • 在给定提取器,变压器和装载机
  • 的情况下,进口商应该知道如何导入

也就是说,进口商绝对不应该实施所有的E-T-L方法。它应该接收或创建E-T-L对象并适当地使用它们。

我会让E-T-L组件成为独立的单元。他们应该知道如何照顾自己:在构建时初始化,在超出范围时进行清理。

我在使用Spring的Java +依赖注入中做过这种事情。我的导入器是真正的胶水代码,只需将Spring收到的E-T-L组件组合在一行代码中。

如果您根据“只做一件事”原则重新考虑您的设计,您的问题可能会自然消失。因为你正在使用Scala,所以尽量避免突变,因为这会自然地驱使你走向更清晰的界面。 (我之所以提到这一点,是因为你的initialize *方法听起来像修改状态。)