3

クライアントコードを次のようにします。

    val config:Config = new MyConfig("c:/etc/myConfig.txt")
    println(config.param1)
    println(config.param2)        
    println(config.param3)

つまり、次のことを意味します。

  • Config インターフェイスは構成フィールドを定義します
  • MyConfig は Config 実装です。必要な配線はすべて、目的の実装のインスタンス化です。
  • データは遅延ロードされます -- 最初のフィールド参照 (この場合は config.param1) で発生するはずです

そのため、交換可能な実装をサポートし、静的に型指定されたフィールドを使用して、遅延読み込みを隠して、クライアント コードを使いやすくしたいと考えています。また、代替の実装を作成するためにできるだけシンプルにしたいので、Config がある程度ガイドするはずです。

私はこれまでに思いついたことに満足していません:

trait Config {
  lazy val param1:String = resolveParam1
  lazy val param2:String = resolveParam2
  lazy val param3:Int = resolveParam3

  protected def resolveParam1:String
  protected def resolveParam2:String
  protected def resolveParam3:Int
}

class MyConfig(fileName:String) extends Config {
  lazy val data:Map[String, Any] = readConfig

  // some dummy impl here, should read from a file
  protected def readConfig:Map[String,Any] = Map[String, Any]("p1" -> "abc", "p2" -> "defgh", "p3" -> 43)

  protected def resolveParam1:String = data.get("p1").get.asInstanceOf[String]
  protected def resolveParam2:String = data.get("p2").get.asInstanceOf[String]
  protected def resolveParam3:Int = data.get("p3").get.asInstanceOf[Int]
}

より良い解決策があると確信しています。それがあなたが助けることができる場所です:)

ここで特に気に入らないことの 1 つは、MyConfig がいくつかの任意のキーを持つ中間コンテナーを定義し、それが Map[String, Any ] であるため、値をキャストする必要があることです。

4

2 に答える 2

1

値を抽象化することを妨げるものは何もありません。スーパートレイトで遅延を強制することはできませんが、遅延読み込みは実際には実装の詳細であるため、問題ありません。

trait Config {
  val param1: String
  val param2: String
  val param3: Int
}

class MyConfig extends Config {
  lazy val param1 = readConfig().("p1")
  ...

  def readConfig(): Map[String, String] = ...
}

文体的readConfig()には、副作用のある方法であるため、(なしではなく)親を使用して宣言および呼び出す必要があります。no-parens構文は、純粋な機能メソッドを示すように設計されています。

于 2008-12-06T06:03:58.427 に答える
0

簡単にしたいだけなら、「param」フィールドはメソッドになる可能性があります...

trait Config {
  def param1:String
  def param2:String
  def param3:Int
}

class MyConfig(fileName:String) extends Config {
  lazy val data:Map[String, Any] = readConfig

  // some dummy impl here, should read from a file
  protected def readConfig:Map[String,Any] = 
    Map[String, Any]("p1" -> "abc", "p2" -> "defgh", "p3" -> 43)

  def param1:String = data.get("p1").get.asInstanceOf[String]
  def param2:String = data.get("p2").get.asInstanceOf[String]
  def param3:Int = data.get("p3").get.asInstanceOf[Int]
}

キャストを取り除くには、MyConfigによって遅延ロードされる非遅延内部クラスをラップすることができますMyConfig

class MyConfig(fileName:String) extends Config {
  private class NonLazyConfig(val p1:String, p2:String, p3:int) extends Config {
      def param1 = p1
      def param2 = p2
      def param1 = p3
  }
  lazy val inner:Config = readConfig

  // some dummy impl here, should read from a file
  protected def readConfig:Config = {
    return new NonLazyConfig("abc", "defgh", 43)
  }
  def param1:String = inner.param1
  def param2:String = inner.param2
  def param3:Int = inner.param3
}
于 2008-12-06T03:56:55.953 に答える