2017-07-11 10 views
0

私はScalaのマルチSBTプロジェクトに取り組んでいます。別のSBTプロジェクトにコアなものを抽出しました。これには、設定、サードパーティのライブラリ(init RMQクライアント、init Redisクライアントなど)および一部のモデルの処理が含まれます。Scalaのコアライブラリを混合するための特性の使用

私は、特性を読み込む設定のようなものをいくつか編成し、必要なところにこの特性を混ぜて、Configuration特性で定義されたconfigのメソッドを使用して特定の環境(環境変数に基づいて)の設定を読み込みます。私はデータベースでも同じことを行ったので、PostgreSQLを読み込み、接続を開いて、必要なところにその特性を組み込み、クエリやその他の実行に使用できるdatabaseメソッドを使用します。

あなたの意見ではこの良いアプローチですか?利点は、私は各プロジェクトでデータベース接続と初期化を処理する必要はなく、コードもずっと短くて済みます。ただし、接続を閉じる際に問題が1つあります。データベースが混在している場所での接続を閉じる場所

トピックに関するご意見はありがとうございます。おかげ

アメール

答えて

1

についての接続、あなたが彼らと一緒に行われたときに(プールに戻る)それらを閉じるする必要があり、それはミックスインする実装直交しています。

の構成と、そのようなに関しては、私はこのアプローチを好むが、それに伴う問題は、ほとんどの時間は、あなたがロードされたconfigのようなものがシングルトンになりたいということですが、あなたは、単に

trait Configuration { 
    val config = loadConfig 
    } 

    class Foo with Configuration 
    class Bar with Configuration 
    val f1 = new Foo 
    val f2 = new Foo 
    val b1 = new Bar 
    val b2 = new Bar 

ような何かを行う場合次に、あなたは設定の4つの異なるコピーをロードすることになります。この周り 一つの方法は、シングルトンオブジェクトにloadConfigを委任することです:

object Configuration { 
    val config = loadConfig 
} 
trait Configuration { 
    def config = Configration.config 
} 

これは動作しますが、それはユニットテストをはるかに困難になり、私がしたい場合は、私の設定は時々、データベースからロードされたものを(機能を無効に? )

別の可能性は、プロキシクラスである:今

trait Configuration { 
    def loadConfig: Config 
    lazy val config: Config = loadConfig 
} 

class ConfigurationProxy(cfg: Configuration) extends Configuration { 
    def loadConfig = cfg.config 
} 

object Main extends App with Configuration { 
    def loadConfig = ??? // executed only one per application 
    ... 
} 

class Foo extends ConfigurationProxy(Main) 
class Bar extends ConfigurationProxy(Main) 

val f1 = new Foo 
val f2 = new Foo 
val b1 = new Bar 
val b2 = new Bar 

、すべての4つの変数が同じConfigインスタンスを見ています。 しかし、あなたはConfigurationを望んでいるどこかの機能を持っている場合、あなたはまだ、これらのいずれかを渡すことができますなど

def connectToDB(cfg: Configuration) = ??? 

connectToDB(Main) 
connectToDB(f1) 
connectToDB(b2) 

関連する問題