これらのタイプのシナリオが発生するため、オブジェクト指向は特に価値があり、複雑さをカプセル化できる抽象化を合理的に設計するツールを提供します。
ここでの本当の質問は、その複雑さをどこでカプセル化しますか?
それでは、少し前に戻り、ここで言及している「複雑さ」についてお話しましょう。あなたの問題(私が理解しているように;私が間違っている場合は修正してください)は、データで完了する必要があるタスクに効果的に使用できるモデルではない永続モデルです。これは、他のタスクのための効果的かつ使用できますが、ないためにも、あなたの仕事。
では、平均値の良いモデルを提示しないデータがある場合はどうしますか?
翻訳します。できるのはそれだけです。その翻訳は私が上で言及した「複雑さ」です。モデルを翻訳することを受け入れたので、いくつかの要因を決定する必要があります。
両方向に翻訳する必要がありますか?次のように、両方向は同じように翻訳されますか?
(Tbl A、Tbl B)-> Obj X(読み取り)
Obj X->(Tbl A、Tbl B)(書き込み)
または、挿入/更新/削除アクティビティは、Obj Xとしてデータを読み取りますが、データはObj Yから挿入/更新されるような異なるタイプのオブジェクトを表しますか?これらの2つの方法のどちらを使用するか、または更新/挿入/削除ができない場合は、翻訳を配置する場所の重要な要素です。
どこで翻訳しますか?
この回答で私が最初に述べた声明に戻ります。OOを使用すると、複雑さをカプセル化できます。ここで言及するのは、必要なだけでなく、すべてのコードに漏れ出ないようにするには、その複雑さをカプセル化する必要があるという事実です。同時に、完璧な抽象化ができないことを認識することが重要です。そのため、非常に効果的で使いやすい抽象化を持つことよりも、それについて心配する必要はありません。
再び今。あなたの問題は次のとおりです。この複雑さをどこに置きますか?さてあなたには選択肢があります。
ストアドプロシージャを使用してデータベースで実行できます。これには、ORMでうまくプレイできないことが多いという欠点がありますが、常にそうとは限りません。ストアドプロシージャには、パフォーマンスなどの利点があります。ただし、ストアドプロシージャには多くのメンテナンスが必要になる場合がありますが、特定のシナリオを分析し、メンテナンスが他の選択肢よりも多いか少ないかを判断するのはユーザー次第です。私は個人的にストアドプロシージャに非常に熟練しており、そのため、利用可能な人材のこの事実はオーバーヘッドを削減します。知っていることに基づいて意思決定を行うことの価値を過小評価しないでください。ユーザーまたはチームが最適なソリューションよりも優れたソリューションを作成および保守する方法を知っているため、次善のソリューションが正しいソリューションよりも最適になる場合があります。
別のデータベース内オプションはビューです。データベースサーバーに応じて、これらは非常に最適または次善であるか、まったく効果的ではない場合があります。欠点の1つは、データベースで使用可能なインデックスオプションに応じたクエリ時間です。データの変更(挿入/更新/削除)を行う必要がない場合は、ビューがさらに良い選択になります。
リポジトリパターンを使用する古いスタンバイがあるデータベースを通過します。これは実績のあるアプローチであり、非常に効果的です。欠点にはボイラープレートが含まれる傾向がありますが、十分にファクタリングされたリポジトリはこれをある程度回避でき、これらが不幸な量のボイラープレートをもたらす場合でも、リポジトリは単純なコードであり、理解しやすく、維持しやすく、優れたAPIを提示する傾向があります/ abstraction。また、リポジトリは、データベース内オプションを使用すると失われる単体テスト可能性に適しています。
自動マッパーのようなツールがあり、ORMを使用してデータベースモデルからormを使用可能なモデルに変換できる可能性がありますが、これらのツールの一部は、魔法のように振る舞うことを維持/理解するのが難しい場合があります。ただし、最小限のオーバーヘッドコードを作成するだけで、十分に理解されていればメンテナンスのオーバーヘッドが少なくなります。
次に、データベースからさらに一歩踏み出します。これは、非翻訳永続モデルを処理するコードの量が増えることを意味し、これは本当に不快になります。これらのシナリオでは、UIに翻訳レイヤーを配置することについて話します。これは一般的に非常に悪い考えであり、時間の経過とともにひどく減衰します。
今の話を始めましょう狂いました。
存在するのObject
は、すべてがすべてを網羅した抽象化だけではありません。コンピュータ科学が研究されてきた長年にわたって、そしてそれ以前にも数学の研究から、多くの抽象化が開発されてきました。私たちが創造的になり始めるなら、研究されている利用可能な既知の抽象化について話を始めましょう。
アクターモデルがあります。これは、他のコードにメッセージを送信するだけで、他のコードにすべての作業を効果的に委任するだけで、複雑さをすべてのコードからカプセル化するのに非常に効果的であるため、これは興味深いアプローチです。これは、「Obj XをYに送信する必要がある」というメッセージを俳優に送信し、場所Yで応答を待機し、Obj Xを処理するレセプタクルがある限り機能します。 「Obj Xと計算Y、Zが必要です」そして、待つ必要さえありません。翻訳はそのメッセージパスの反対側で行われ、その結果の読み取りが必要ない場合は先に進むことができます。これは、目的のためにアクターモデルをわずかに乱用する可能性がありますが、すべて依存しています。
別のカプセル化境界はプロセス境界です。これらは、複雑さを非常に効果的に分離するために使用できます。通信が単純なHTTPであるSOAP、RESTを使用するWebサービスとして、または独自のプロトコルが必要な場合(推奨されない)、翻訳コードを作成できます。STOMPは完全に悪い新しいプロトコルではありません。または、システムローカルで公開されているメモリパイプを備えた通常のデーモンサービスを使用して、選択したプロトコルを使用して再び非常に迅速に通信します。これには実際にかなり良い利点があります:
- 古いバージョンと新しいバージョンのサポートの翻訳を同時に行う複数のプロセスを実行して、翻訳サービスを更新してオブジェクトモデルV2を公開し、後で個別に新しいコードを使用するように消費コードを更新できます。モデル。
- プロセスをパフォーマンスのためにコアに固定するなどの興味深いことを行うことができます。また、このアプローチでは、そのデータに触れるセキュリティ特権で実行される唯一のプロセスを作成することにより、セキュリティの安全性を確保します。
- 翻訳スペースでコードを書くことは翻訳スペースの外で呼び出すことができないため、固定されたままになるプロセス境界について話しているとき、非常に強力な境界が得られます。プロセス範囲を共有せず、契約ごとに使用シナリオの固定セットを確保します。
- 非同期/非ブロッキング更新がより簡単になります。
欠点は明らかに一般的に必要なものよりも多くのメンテナンスであり、通信オーバーヘッドがパフォーマンスとメンテナンスに影響します。
複雑さをカプセル化する方法は非常に多様であり、その複雑さをシステムのさらに奇妙で奇妙な場所に配置することができます。高次関数の形式(多くの場合、戦略パターンまたはオブジェクトパターンのその他のさまざまな奇妙な形式を使用して偽造されたもの)を使用すると、非常に興味深いことができます。
そうです、モナドについて話を始めましょう。必要な独立した翻訳を行う小さな特定の関数の非常に独立した方法でこの翻訳レイヤーを作成できますが、これらの翻訳関数をすべて非表示にして、外部コードからほとんどアクセスできないようにします。これには、外部コードにあまり影響を与えずに簡単に変更できるように、それらへの依存を減らすという利点があります。次に、優れたOOモデルタイプオブジェクトのいずれかで機能する高階関数(匿名関数、ラムダ関数、ストラテジオブジェクト、ただしそれらを構造化する必要があります)を受け入れるクラスを作成します。次に、これらの関数を受け入れる基礎コードに、適切な変換メソッドを使用したリテラル実行を実行させます。
これにより、すべてのコードから離れた境界の反対側にすべての翻訳が存在するだけでなく、境界が作成されます。それはその側でのみ使用され、コードの残りの部分は、その境界のエントリポイントがどこにあるか以外、それについて何も知ることさえできません。
ええ、それは本当におかしな話ですが、誰が知っていますか。あなたはただ狂ったかもしれません(真剣に、88%未満の狂気の評価でモナドを引き受けないでください、人体傷害の本当の危険があります)。