0

多くの共通コードを持ついくつかのクラスを持つ Scala プログラムがあります。多くのコードは汎用的なため、次のようなものがあります (TypeTags を使用して型情報を保持します):

object ModelA {

    def update(id: UUID, changes: Map[String, Any]) = {
        Validate.partialInstanceOf[ModelA](changes) match {
            ...
        }
    }

}

と ...

object ModelB {

    def update(id: UUID, changes: Map[String, Any]) = {
        Validate.partialInstanceOf[ModelB](changes) match {
            ...
        }
    }

}

私は Scala にかなり慣れていないので、このコードを DRY 化する最良の方法は何かと考えていました。トレイトまたはヘルパー クラスの 2 つの可能性があります。これは私が特性のために念頭に置いていたことです:

trait Model[M <: Model] {
    def update(id: UUID, changes: Map[String, Any]) = {
        Validate.partialInstanceOf[M](changes) match {
            ...
        }
    }
}

object ModelA extends Model[ModelA]
object ModelB extends Model[ModelB]

...そして、これはヘルパークラスについて私が念頭に置いていたことです:

object ModelHelper {
    def update[M](id: UUID, changes: Map[String, Any]) = {
        Validate.partialInstanceOf[M](changes) match {
            ...
        }
    }
}

object ModelA {

    def update(id: UUID, changes: Map[String, Any]) = {
        ModelHelper.update[ModelA](id, changes);
    }

}
...

私の質問は次のとおりです。より慣用的な Scala アプローチは何ですか? 子の型を親の特性に渡すことは、私にはちょっと面倒に思えます。これは大丈夫ですか?

4

2 に答える 2

3

DRYer であるため、trait を使用する方が慣用的です。Scala ライブラリはあらゆる場所でそれを行います。たとえば、次のようになります。

object ArrayBuffer extends SeqFactory[ArrayBuffer] ...
于 2013-07-24T20:53:37.800 に答える
2

機能のさまざまな側面を提供する複数のトレイトを混在させる可能性が高く、そのすべてがどの特定のタイプで動作しているかを知る必要がある場合は、次のようなパターンを検討することをお勧めします。

trait Updatable {
    type M
    def update(id: UUID, changes: Map[String, Any]) = {
        Validate.partialInstanceOf[M](changes) match {
            ...
        }
    }
}

trait Jsonable {
    type M
    def toJson(model: M) = {
        ...
    }
}

... other functionality traits ...

object ModelA extends Updatable with Jsonable with ... { type M = ModelA.type }
object ModelB extends Updatable with Jsonable with ... { type M = ModelB.type }
class ModelC extends Updatable with Jsonable with ... { type M = ModelC } // Example for class types rather than objects, if that is relevant.

その後、各特性の機能を個別にテストでき、次のようなものを書き始める必要はありませんobject ModelD extends Updatable[ModelD] with Jsonable[ModelD] with ...

于 2013-07-24T21:11:18.063 に答える