2017-06-24 8 views
0

データベースのやりとりを扱う関数がいくつかあります。 (readModelById、updateModel、findModelsなど)を使用して、機能的スタイルで使用しようとしています。DBハンドルの扱いと関数型プログラミングの初期化

OOPでは、コンストラクタでDB接続パラメータを受け取り、データベース接続を作成し、インスタンスにDBハンドルを保存するクラスを作成します。関数は、 "this"からDBハンドルを使用するだけです。

これを処理するには、FPではどのような方法が最適ですか?私はアプリケーション全体を通してDBハンドルを手渡したくありません。私は、ハンドルを "焼く"機能の部分的なアプリケーションについて考えましたが、それは醜い定型コードを作成し、それを1つずつ実行して戻します。

このようなFPのベストプラクティス/デザインパターンは何ですか?

答えて

0

これは副作用であるため、データベース操作は関数型プログラミングの対象ドメインではありません。 FPの主な価値は、可能であれば純粋な関数を使うことにあります。

しかし、OOPにはこれと並行して、データベースリソースをパラメータとして取ることが適切な方法であると示唆されることがあります。 SOLIDの原則を使用してOOPのDB実装を検討してください。 Interface Segregation Principleのため、DBメソッドごとのインターフェイスとインターフェイスごとに少なくとも1つの実装クラスになります。

l

次に、ユースケースを実行するために、DB操作のセット全体ではなく、必要な依存関係のみを渡します。 (ISaveRegistrationが存在し、上記のように定義されていると仮定します)。どこかでこのコードが呼び出された場所の上

// C# 
public async Task Register(
    IGetRegistrations a, 
    ISaveRegistration b, 
    RegisterRequest requested 
    ) 
{ 
    var registrations = await a.GetRegistrations(requested.Date); 

    // examine existing registrations and determine request is valid 
    // throw an exception if not? 
    ... 

    return await b.SaveRegistration(...); 
} 

、あなたは、これらのインタフェースの実装まで新に持っているとDbResourceとそれらを提供。

var a = new GetRegistrationsImpl(db); 
var b = new SaveRegistrationImpl(db); 
... 
return await Register(a, b, request); 

注:あなたは、いくつかの決まり文句を避けるためにしようとするためにここにDIフレームワークを使用することができます。しかし、私はそれがピーターからポールを借りて借りていることがわかります。あなたは、DIフレームワークを学ばなくても、自分自身の依存関係を配線するときと同じように、DIフレームワークをどのように動作させるかを決めることができます。それは新しいチームメンバーが学ばなければならない別の技術です。

FPでは、DBリソースをパラメータとして使用する関数を定義するだけで同じことができます。インタフェースを実装しているクラスにラップするのではなく、直接関数を渡すことができます。

// F# 
let getRegistrations (DbResource : db) (day : DateTime) = 
    ... 

let saveRegistration (DbResource : db) ... = 
    ... 

ユースケース機能:

// F# 
let register fGet fSave request = 
    async { 
     let! registrations = fGet request.Date 

     // call your business logic here 
     ... 

     do! fSave ... 
    } 

は、その後、あなたがこのような何かを行う可能性があり、それを呼び出す:

register (getRegistrations db) (saveRegistration db) request 

ここdbの部分的なアプリケーションは、注射をコンストラクタに似ています。あなたの "損失"が複数の機能に渡ることは、各DB操作のためのインタフェース+実装を定義する必要がないという節約と比べて最小限です。


機能 - 第一言語であるにもかかわらず、上記は原則的にOO/SOLIDと同じです...コードの行数が少なくて済みます。機能領域への一歩を進めるためには、ビジネスロジックの副作用をなくす必要があります。副作用には、現在時刻、ランダム、例外のスロー、データベース操作、HTTP API呼び出しなどがあります。

F#では副作用を宣言する必要はないため、副作用を使用しない場所を指定します。私の場合、ユースケースレベル(上記のregister関数)が副作用の最後の場所です。それより低いビジネスロジックがあれば、私はそれらをユースケースにプッシュします。それは、それを行う学習プロセスですので、最初は不可能と思われる場合は落胆しないでください。今はあなたが持っていることをして、あなたが行くにつれて学びます。

私はa postを持っています。これは、FPの利点とその入手方法に関する正しい期待を設定しようとしています。

関連する問題