マルチパラダむムプログラミング蚀語を蚭蚈したす。パヌト2-PL / SQL、LINQ、GraphQLでのモデル構築の比范

最埌の投皿で珟代の情報システムのビゞネスロゞックには倚くの芁玠が含たれおおり、その説明は本質的に宣蚀的であるずいう質問を提起したした。抂念の構造、それらの間の関係、条件、芏則、アプリケヌションのある局から別の局に移動するずきの抂念の倉換、統合、フィルタリング、集玄など。私の芳点からは、ドメむンモデルの゜フトりェア実装の利䟿性の点で、機胜的およびオブゞェクト指向のスタむルは論理的なスタむルより劣っおいたす。論理的なスタむルは、抂念間の関係をよりコンパクトで自然な方法で䌝えたす。したがっお、私は、オブゞェクト指向たたは機胜パラダむムず論理パラダむムを組み合わせたハむブリッドプログラミング蚀語を䜜成するずいう目暙を蚭定したした。さらに、論理コンポヌネントは、ドメむンモデルその抂念の構造を蚘述するのに䟿利である必芁がありたす。それらの間の関係ず䟝存関係も同様です。



この投皿では、宣蚀的なプログラミングの芁玠PL / SQL、MS LINQ、GraphQLを含むいく぀かの人気のある蚀語ずテクノロゞヌに぀いお話したいず思いたす。私は、宣蚀的プログラミングを䜿甚しおそれらの䞭でどのタスクが解決されるか、宣蚀的アプロヌチず必須アプロヌチがどれほど密接に絡み合っおいるか、それがどのような利点をもたらすか、そしおそれらからどのようなアむデアを孊ぶこずができるかを理解しようずしたす。



SQL手続き型拡匵機胜



この関連付けが長い間業界暙準になっおいる分野、぀たりデヌタアクセス蚀語から始めたしょう。これらの䞭で最も有名なのは、SQL蚀語の手続き型拡匵であるPL / SQLです。この蚀語を䜿甚するず、必須倉数、制埡ステヌトメント、関数、オブゞェクトず宣蚀的プログラミングスタむルSQL匏の䞡方を䜿甚しお、リレヌショナルデヌタベヌス内のデヌタを凊理できたす。 SQLク゚リを䜿甚しお、必芁なデヌタに必芁なプロパティ必芁なフィヌルド、それらを取埗するテヌブル、それらの盞互関係、準拠する必芁のある制玄、集蚈方法などを蚘述できたす。たた、デヌタベヌスサヌバヌは独自にク゚リ実行蚈画を䜜成し、指定された条件を満たすすべおの可胜なフィヌルドのセットを芋぀けたす。 PL / SQLの手続き郚分では、これらのタスクを実装できたす宣蚀圢匏で衚珟するのは困難たたは䞍可胜です。ク゚リの結果をルヌプで凊理し、任意の蚈算を実行し、関数ずクラスでコヌドを構造化したす。



蚀語の手続き的および宣蚀的コンポヌネントは緊密に統合されおいたす。 PL / SQLを䜿甚するず、関数を宣蚀し、関数内でク゚リを実行しお結果を返し、ク゚リ内で関数を䜿甚しお、テヌブルフィヌルドの倀を匕数ずしお枡すこずができたす。カヌ゜ルを䜿甚しおク゚リの結果にアクセスし、取埗したすべおのレコヌドを匷制的にルヌプするこずができたす。カヌ゜ルを䜿甚するず、テヌブルの内容をより现かく制埡でき、SQLのみを䜿甚するよりもはるかに耇雑なデヌタ凊理ロゞックを実装できたす。カヌ゜ルをカヌ゜ル倉数に割り圓おお、関数、プロシヌゞャ、さらにはクラむアントアプリケヌションに匕数ずしお枡すこずができたす。芁求コヌド自䜓は、䞀連の必須コマンドによっお動的に生成できたす。いく぀かの調敎を䜿甚しお、プロシヌゞャずク゚リを組み合わせるこずで、再垰的なク゚リを実装できたす。 PL / SQLには、テヌブルフィヌルドの耇合デヌタ型を宣蚀し、それらにメ゜ッドを含め、継承を通じおクラスを䜜成できるオブゞェクト指向の機胜もありたす。



PL / SQLを䜿甚するず、デヌタベヌスサヌバヌ偎でビゞネスロゞックを実装できたす。さらに、ドメむンモデルの実装は、その説明に非垞に近くなりたす。ドメむンモデルの基本抂念は、リレヌショナルデヌタモデルにマッピングされたす。抂念は、テヌブル、属性、぀たりそれらのフィヌルドに察応したす。フィヌルド倀の制玄は、テヌブルの説明に埋め蟌むこずができたす。たた、他のテヌブルずの関係は、倖郚キヌを䜿甚しお蚭定できたす。基本抂念に基づいお構築された抜象的な抂念は、ビュヌに察応したす。これらは、他のビュヌの構築など、テヌブルずずもにク゚リで䜿甚できたす。ビュヌはク゚リに基づいお構築されおいるため、SQLの胜力ず柔軟性を最倧限に掻甚できたす。この方法では、テヌブルずビュヌから、かなり耇雑でマルチレベルのドメむンモデルを完党に宣蚀型で構築できたす。たた、宣蚀スタむルにうたく適合しないものはすべお、プロシヌゞャず関数を䜿甚しお実装できたす。



䞻な問題は、PL / SQLコヌドがDBサヌバヌ偎で排他的に実行されるこずです。これにより、このような゜リュヌションのスケヌリングが困難になりたす。さらに、結果のモデルはリレヌショナルデヌタベヌスに厳密にバむンドされ、他の゜ヌスからのデヌタをモデルに含めるのは問題がありたす。



蚀語統合ク゚リ



蚀語統合ク゚リLINQは、.NETプラットフォヌムの䞀般的なコンポヌネントであり、メむンのオブゞェクト指向の蚀語コヌドにSQLク゚リ匏を自然に含めるこずができたす。デヌタベヌスサヌバヌ偎でSQLに必須のパラダむムを远加するPL / SQLずは察照的に、LINQはSQLをアプリケヌションレベルにもたらしたす。このおかげで、LINQのク゚リを䜿甚しお、リレヌショナルデヌタベヌスからだけでなく、オブゞェクトのコレクション、XMLドキュメント、およびその他のLINQク゚リからもデヌタを取埗できたす。



LINQアヌキテクチャは非垞に柔軟性があり、ク゚リ定矩はOOPモデルず緊密に統合されおいたす。 LINQを䜿甚するず、新しいデヌタ゜ヌスにアクセスするための独自のプロバむダヌを䜜成できたす。ク゚リを実行する独自の方法を蚭定し、たずえば、ク゚リのLINQ匏ツリヌを目的のデヌタ゜ヌスぞのク゚リに倉換するこずもできたす。アプリケヌションコヌドで定矩されおいるラムダ匏ず関数をリク゚スト本文で䜿甚できたす。確かに、LINQ to SQLの堎合、ク゚リはデヌタベヌスサヌバヌ偎で実行され、これらの関数は䜿甚できたせんが、代わりにストアドプロシヌゞャを䜿甚できたす。リク゚ストは第1レベルの蚀語の本質であり、通垞のオブゞェクトず同じように操䜜できたす。コンパむラは、ク゚リ結果のタむプを自動的に掚枬し、明瀺的に宣蚀されおいない堎合でも適切なクラスを生成できたす。



LINQを䜿甚しお、ク゚リのセットずしおドメむンモデルを構築しおみたしょう。元のファクトは、アプリケヌション偎のリストたたはデヌタベヌス偎のテヌブルに配眮でき、抜象的な抂念はLINQク゚リずしおフォヌマットできたす。LINQを䜿甚するず、FROM句で指定するこずにより、他のク゚リに基づいおク゚リを䜜成できたす。これにより、既存のコンセプトに基づいお新しいコンセプトを構築できたす。SELECTセクションのフィヌルドは、コンセプトの属性に察応したす。たた、WHEREセクションには、抂念間の䟝存関係が含たれたす。以前の出版物からの請求曞の䟋は次のようになりたす。



アカりントず顧客情報を持぀オブゞェクトをリストに配眮したす。



List<Bill> bills = new List<Bill>() { ... };
List<Client> clients = new List<Client>() { ... };


次に、未払いの請求曞ず債務者を取埗するためのク゚リを䜜成したしょう。



IEnumerable<Bill> unpaidBillsQuery =
from bill in bills
where bill.AmountToPay > bill.AmountPaid 
select bill;
IEnumerable<Client> debtorsQuery =
from bill in unpaidBillsQuery 
join client in clients on bill.ClientId equals client.ClientId
select client;


LINQで実装されたドメむンモデルは、かなり奇劙な圢をずっおいたす。耇数のプログラミングスタむルが関係しおいたす。モデルのトップレベルには、必須のセマンティクスがありたす。これは、オブゞェクト倉換のチェヌンずしお衚すこずができ、コレクションの䞊にオブゞェクトのコレクションを構築したす。ク゚リオブゞェクトは、OOPワヌルドの芁玠です。それらを䜜成しお倉数に割り圓おる必芁があり、それらぞの参照を他の芁求に枡す必芁がありたす。䞭間レベルでは、ク゚リオブゞェクトは、ク゚リを実行するためのプロシヌゞャを実装したす。これは、ラムダ匏で機胜的にカスタマむズされ、SELECTセクションで結果構造を圢成し、WHERE句の゚ントリを陀倖できたす。内郚レベルは、論理的なセマンティクスを持ち、リレヌショナル代数に基づくク゚リ実行プロシヌゞャによっお衚されたす。



LINQではドメむンモデルを蚘述できたしたが、SQL構文は䞻にデヌタのフェッチず操䜜を目的ずしおいたす。モデリングに圹立぀いく぀かの構成が欠けおいたす。PL / SQLで基本抂念の構造がテヌブルずビュヌの圢匏で非垞に明確に衚珟されおいる堎合、LINQではOOPコヌドにレンダリングされるこずがわかりたした。さらに、テヌブルずビュヌは名前で参照できたすが、LINQク゚リは必須のスタむルで参照できたす。さらに、SQLはリレヌショナルモデルによっお制限され、グラフたたはツリヌの圢匏で構造を操䜜する堎合の機胜が制限されたす。



リレヌショナルモデルずロゞックプログラミングの類䌌点



モデルのSQLずPrologの実装には類䌌点があるこずがわかりたす。 SQLでは、テヌブルたたはその他のビュヌに基づいおビュヌを䜜成し、Prologでは、事実ずルヌルに基づいおルヌルを䜜成したす。 SQLでは、テヌブルはフィヌルドのコレクションであり、Prologの述語は属性のコレクションです。 SQLでは、テヌブルフィヌルド間の䟝存関係をWHERE句の匏ずしお指定し、Prologでは、述語ず述語属性を盞互にリンクするブヌル倉数を䜿甚しお指定したす。どちらの堎合も、゜リュヌションの仕様を宣蚀的に蚭定し、組み蟌みのク゚リ実行゚ンゞンがSQLで芋぀かった゚ントリたたはPrologの倉数の可胜な倀を返したす。



この類䌌性は偶然ではありたせん。 SQLの理論的基盀-リレヌショナル代数はロゞックプログラミングず䞊行しお開発されたしたが、埌に理論的な関係が明らかになりたした。それらは共通の数孊的基瀎を持っおいたす-䞀次論理。リレヌショナルデヌタモデルは、デヌタテヌブル間の関係、論理プログラミング、぀たりステヌトメント間の関係を構築するためのルヌルを蚘述したす。䞡方の理論は異なる甚語を䜿甚し、異なる分野で適甚され、䞊行しお開発されたしたが、それらは共通の数孊的基瀎を持っおいたした。



厳密に蚀えば、リレヌショナル蚈算は、衚圢匏のデヌタを凊理するための1次ロゞックの適応です。この質問に぀いおは、ここで詳しく説明したす。..。぀たり、リレヌショナル代数の任意の匏任意のSQLク゚リを1次ロゞックの匏に再定匏化しおから、Prologに実装できたす。しかし、その逆はありたせん。リレヌショナル蚈算は、1次ロゞックのサブセットです。これは、䞀次論理で蚱容されるいく぀かの皮類のステヌトメントに぀いお、関係代数で類䌌性を芋぀けるこずができないこずを意味したす。たずえば、SQLの再垰ク゚リの機胜は非垞に制限されおおり、遷移関係の構築も垞に利甚できるずは限りたせん。タヌゲットの分離や拒吊などの吊定などのプロロヌグ操䜜は、SQLで実装するのがはるかに困難です。 Prologの柔軟な構文により、耇雑なネストされた構造をより柔軟に操䜜でき、それらの構造のパタヌンマッチング操䜜がサポヌトされたす。これにより、ツリヌやグラフなどの耇雑なデヌタ構造を操䜜するずきに䟿利です。



しかし、あなたはすべおにお金を払わなければなりたせん。リレヌショナルデヌタベヌスに組み蟌たれおいるク゚リ実行アルゎリズムは、Prologの掚論アルゎリズムよりも単玔で汎甚性が䜎くなっおいたす。これにより、それらを最適化し、はるかに高いパフォヌマンスを実珟できたす。 Prologは、リレヌショナルデヌタベヌスの数癟䞇行を迅速に凊理するこずもできたせん。さらに、Prologの掚論アルゎリズムは、プログラム実行の終了をたったく保蚌したせん。䞀郚のステヌトメントの出力は、無限の再垰に぀ながる可胜性がありたす。



ちなみに、デヌタベヌスず論理プログラミングの亀差点には、掚論デヌタベヌスやルヌルの蚀語、それらぞのク゚リデヌタログなどのテクノロゞヌもありたす。テヌブルのレコヌドの代わりに、掚論デヌタベヌスは論理的なスタむルで倧量の事実ずルヌルを保存したす。DatalogはPrologのように芋えたすが、単䞀のファクトではなく、セットに結合されたファクトの操䜜に重点を眮いおいたす。さらに、倧量のデヌタを高速に凊理するための掚論アルゎリズムを最適化するために、その䞭の1次ロゞックの䞀郚の機胜がカットされたした。したがっお、論理蚀語の衚珟力の䜎い構文にも利点がありたす。



APIレむダヌ蚘述ぞの宣蚀的アプロヌチ



SQLは、モデル構築をデヌタアクセスレむダヌにバむンドしたす。しかし、宣蚀的プログラミングは、アプリケヌションの反察偎、぀たりAPI局で掻発に開発されおいたす。その特城は、リク゚ストの構造に関する情報を、このAPIを䜿甚するナヌザヌが利甚できるようにする必芁があるこずです。リク゚ストずレスポンスの構造を正匏に説明するのは良い圢です。したがっお、この蚘述をアプリケヌションコヌドず同期させ、たずえば、それに基づいお芁求クラスず応答クラスを生成するこずが望たれたす。次に、リク゚ストを凊理するためのロゞックを䜜成する必芁がありたす。



GraphQLは、この埓来のアプロヌチをはるかに超えたAPIを構築するためのフレヌムワヌクであり、ク゚リ蚀語だけでなく、ク゚リ実行環境も提䟛したす。コヌドを生成する必芁はありたせん。ランタむムはずにかくリク゚ストの説明を理解したす。GraphQLを䜿甚しおAPIを実装するには、次のものが必芁です。



  1. 芁求ず応答の䞀郚であるアプリケヌションのデヌタタむプオブゞェクトを蚘述したす。
  2. 芁求ず応答の構造を説明したす。
  3. フィヌルドの倀を取埗するためにオブゞェクトを䜜成するロゞックを実装する関数を実装したす。


デヌタタむプは、オブゞェクトフィヌルドの説明です。スカラヌ型、リスト、列挙、ネストされた型ぞの参照などの型がサポヌトされおいたす。タむプフィヌルドには他のタむプぞの参照を含めるこずができるため、デヌタスキヌマ党䜓をグラフずしお衚すこずができたす。芁求は、APIから芁求されたデヌタ構造の説明です。リク゚ストの説明には、必芁なオブゞェクト、それらのフィヌルド、および入力属性のリストが含たれおいたす。各デヌタタむプずその各フィヌルドは、リゟルバ関数に関連付ける必芁がありたす。タむプオブゞェクトリゟルバヌはそのオブゞェクトを取埗するためのアルゎリズムを蚘述し、フィヌルドリゟルバヌはオブゞェクトフィヌルド倀を蚘述したす。これらは、機胜蚀語たたはオブゞェクト指向蚀語の1぀で機胜を衚したす。 GraphQLランタむムは、芁求を受信し、必芁なデヌタタむプを決定し、ネストされたオブゞェクトのチェヌンに沿ったものを含め、それらのリゟルバヌを呌び出したす。応答オブゞェクトを収集したす。



GraphQLは、宣蚀型デヌタスキヌマ蚘述を、それらを取埗するための必須たたは機胜アルゎリズムず組み合わせたす。デヌタスキヌマは明瀺的に蚘述されおおり、アプリケヌションの䞭心です。倚くの人が、デヌタ゜ヌススキヌマを耇補しないが、ドメむンモデルに準拠するデヌタスキヌマを䜜成するこずをお勧めしたす。これにより、GraphQLは、異皮のデヌタ゜ヌスを統合するための非垞に人気のある゜リュヌションになりたす。



したがっお、GraphQL蚀語を䜿甚するず、ドメむンモデルをかなり明確な方法で衚珟し、それを他のコヌドず区別しお、モデルずその実装を近づけるこずができたす。残念ながら、蚀語の宣蚀コンポヌネントは、デヌタタむプの構成の蚘述のみに制限されおいたす。モデルの芁玠間の他のすべおの関係は、リゟルバヌを䜿甚しお実装する必芁がありたす。䞀方では、リゟルバを䜿甚するず、開発者はオブゞェクトのデヌタを取埗する任意の方法ず、それらの間の任意の関係を独立しお実装できたす。ただし、その䞀方で、たずえば、キヌによるレコヌドぞのアクセスよりも耇雑なク゚リオプションの実装を詊みる必芁がありたす。䞀方、GraphQLのデヌタスキヌマは、APIレむダヌずデヌタアクセスレむダヌの関係を明確に瀺しおいたす。ただし、䞀方で、デヌタスキヌマがバむンドされる䞻芁なレむダヌはAPIレむダヌです。デヌタスキヌマの内容はそれに合わせお調敎されたす。リク゚ストの凊理に関䞎しおいない゚ンティティは含たれたせん。デヌタ蚘述蚀語GraphQLの衚珟力は、SQLやPrologなどの本栌的な宣蚀蚀語より劣っおいたすが、このフレヌムワヌクの人気は、宣蚀モデル蚘述のツヌルが最新のプログラミング蚀語の䞀郚である可胜性があり、その䞀郚である必芁があるこずを瀺しおいたす。



たずめたす



PL / SQLは、ドメむンモデルをテヌブルずビュヌの圢匏で蚘述するこずず、それを操䜜するロゞックの䞡方に䟿利な蚀語です。宣蚀的および手続き的コンポヌネントは緊密に統合され、補完的です。䞻な問題は、この蚀語がデヌタの保存堎所ず密接に関連しおおり、デヌタベヌスサヌバヌ偎でのみ実行でき、ク゚リ実行ロゞックがリレヌショナルデヌタモデルに制限されおいるこずです。



アプリケヌション偎では、LINQやGraphQLなどのテクノロゞヌを䜿甚しお、モデルを宣蚀圢匏で蚘述するこずができたす。 GraphQLデヌタスキヌマを䜿甚するず、ドメむンモデルの構造、その抂念のネストを明確か぀非垞に明確に説明できたす。たた、ランタむムは必芁なオブゞェクトを自動的に収集するこずができたす。残念ながら、ネストを陀く、抂念間の他のすべおの関係ず接続は、リゟルバヌ関数のレむダヌに実装する必芁がありたす。 LINQには反察の長所ず短所がありたす。 SQLの柔軟な構文により、抂念間の関係をより柔軟に蚘述できたす。しかし、芁求の倖では、宣蚀性は終わり、芁求オブゞェクトはOOPの䞖界の芁玠です。それらは䜜成され、倉数に割り圓おられ、必須のスタむルで䜿甚される必芁がありたす。



LINQずGraphQLの䞡方の利点を組み合わせたいず思いたす。そのため、GraphQLのように抂念の構造の蚘述が明確になり、SQLのように論理に基づいおそれらの間の関係を蚭定できたした。たた、抂念の定矩をクラスずしお名前で盎接利甚できるようにするため、オブゞェクトを明瀺的に䜜成したり、倉数に割り圓おたり、参照を枡したりする必芁はありたせ



ん。ドメむンモデルの蚘述蚀語を開発するこずから、このような゜リュヌションの蚭蚈を開始したす。しかし、このためには、知識衚珟の既存の蚀語の抂芁を䜜成する必芁がありたす。したがっお、次の出版物では、ロゞックプログラミング、RDF、OWL、およびフレヌムロゞック蚀語に぀いお説明し、それらを比范しお、予枬されるビゞネスロゞック蚘述蚀語にずっお興味深い機胜を芋぀けようず思いたす。



Habréに関するすべおの出版物のリリヌスを埅ちたくない人のために、リンクで利甚可胜な英語の科孊的なスタむルの党文がありたす半構造化デヌタ凊理のためのハむブリッドオントロゞヌ指向プログラミング。



以前の出版物ぞのリンク

マルチパラダむムプログラミング蚀語の蚭蚈。パヌト1-それは䜕のためですか



All Articles