ORMのスコア

こんにちは、Habr!



Hexletの人々にプログラミングを教えますが、 だまそうとします。たとえば、単純なPHPコースを装って、抽象化、再帰、ファーストクラス関数、クロージャ、畳み込みについて人々に伝え、一般にMITの「プログラミングの基礎」を開始しますSIKP a。ただし、クラスおよび金型からではありません。 このコースや他のコース、および通常のウェビナーでは 、関数型プログラミング、最新のアプローチの問題、主な悪について述べています。 私たちのチャットでは 、大規模な議論が絶えず起こります。そこでは、可変状態が時々システムの複雑さを増すことがわかります。



本日、人気のRuby用DataMapperの作成者の1人であるPiotr Solnitsaがデータベースとの対話について同様の方法で語る記事の翻訳を公開しています。



* * *



私は長い間Rubyで関数型アプローチを推進してきましたが、多くの異なるメソッドやモデルが含まれていますが、すべてを変える1つのアイデア、1つの基本的なアイデア、不変性(不変性)があります。



しかし、それはRubyではどういう意味ですか? オブジェクトの変更を禁止しますか? 遅すぎるので、いいえ。 イミュニティ指向の設計とは、オブジェクトを変更できるインターフェースを避けることを意味します。 はい、Rubyの多くのメソッドは状態を変更しますが、オブジェクトインターフェイスを開発する場合、オブジェクトが変更されないように作成できます。



不変オブジェクトの使用は、私にとって衝撃的な発見でした。 その発見の後に私が気づいたことの1つは、オブジェクトリレーショナルマッピング(ORM)が悪い考えである理由であり、そのために不必要に複雑になっています。



私は約10年間、さまざまなORMのユーザーでした。これには、Data Mapperプロジェクトのワーキンググループに2年ほど含まれ、さらに、Active Recordモデルのすべての障害を克服することになっていた新しいバージョンを作成しようとして2年ほど含まれています。 それらを外側から見た、内側から見た、そしてもうORMに対処したくない。 私で十分。



ORMで得点しました。



難易度



ソフトウェアを作成するときは、できるだけ複雑さを最小限に抑えることに焦点を合わせる必要があります。



オブジェクトリレーショナルマッピングは、オブジェクトを変更してデータベースに永続的に保存するためだけに存在する、追加の複雑さの層にすぎません。



OOPの主なアイデアの1つは、抽象化の使用です。抽象化は、実世界の概念を表し、コードの説明と理解を容易にします。 私たちは長い間この概念に固執してきたので、多くの人々はそれ以上のものをほとんど見ることができません。



しかし、何が起きているのかを理解しやすく、「住所を変更するユーザー」や「商品が追加されるリスト」に対処する必要がないような方法でオブジェクトを作成できます。 ユーザーやシーケンス番号などのエンティティを表すオブジェクトを作成する代わりに、ビジネストランザクション、サブジェクト指向プロセスをモデル化する方法について考えてみてください。



ヒント:すべてを単純にデータを変換する関数としてモデル化できることを理解してください。



適合性の喪失



ORMの背後にある複雑さは、オブジェクトモデルとリレーショナルモデルの不一致と呼ばれるものが原因です。 多くの異なるデータベースモデルとオブジェクトを表現する多くの異なる方法があるため、このタスクは非常に困難です。



次の2つのオプションがあります。



  1. データベースモデルとオブジェクト間の1対1のマッピングを受け入れます。

  2. データベース内のオブジェクトの表現をメモリ内のオブジェクトの表現に接続する複雑なシステムを使用します。





そして、両方のオプションはひどいです。



最初のものは特に怖いです、そして、Rubyコミュニティの多くの人々は理由を知っています。 1:1マッピングにより、アプリケーション層がデータベースにしっかりと接続されるためです。 Active Record ORMは、これがアプリケーションをどのように複雑にするかを理解するのに十分な長さで使用しています。



Data Mapperテンプレートとして知られる2番目のオプションはどうですか? Rubyにはそのようなことはありませんが、Rubyを構築しようとしている人はまだいます。 さらに、このテンプレートを実装しようとしているプロジェクトがすでにいくつかあります。



現実には、オブジェクトモデルとリレーショナルモデルの不一致の問題を解決することさえできませんでした。



何よりも、それを解決することはできません。 特定のプログラミング言語の制限を考えると、可能な場合のみすべてを改善できます。 そして最終的に、人々は間違いなく自分の手でSQLクエリを書くことに切り替えます。



データベースは存在しませんか?



実際、存在します。 そして、これはスタックの最も強力な部分の1つです。 これについて少し考えてみましょう:



データベースが存在しないふりをして、オブジェクトを変更して永続的に保存できるようにします。







私はすべてがあなたが慣れている方法ではないことを理解しています。 通常、「データベースが実装の詳細になる、適切な抽象化」、「データベースの変更が容易になる」、「データベースからオブジェクトが分離されるため、システムの構築が容易になる」などの素晴らしいことについて話します。



しかし、実際に何が起こるのでしょうか? 「オブジェクトを変更し、それらを永続的に保存したい。」



ドメインロジックを永続性の詳細から分離し、同時にORMと可変オブジェクトに伴うすべての複雑さを回避できると言ったらどうでしょうか。



2つの魔法の言葉:関数とデータ型。



ユーザーが存在しません



ユーザーが存在しない、注文が存在しない



ActiveProductShippingContainerHolyMolyManagerはありません。



サーバーに 要求を送るクライアントだけがいます 。 要求には、サーバーがそれを応答に変換するために使用するデータが含まれています。



この相互作用をモデル化できる最も近いものは、入力を受け入れて出力を返す関数です。 実際、これらは常に最終的に答えを返す関数のグループです。



これを見れば、不快な抽象化を思いつく必要はありません。それは、快適さの錯覚のために取っておきます。



データはどうですか? データは複雑さを意味するので、オブジェクトの後ろに隠しますよね? それは、 広告の本のようには機能しないということです。



不規則で予測不可能な動作を伴うデータからのビネグレット-それがORMです。



しかし、どのように? なんで?



混乱は、アプリケーションがどのタイプのデータを処理しているかを正確に判断できないために発生します。 生の入力を直接ORMレイヤーに送信し、最善の結果を期待しています。 オブジェクトは可変であり、予測可能性があるため、副作用の予測が困難であるため、予測不能が発生します。 副作用はバグにつながります。



ユーザーのデータ型を決定でき、この型が無効な状態の不可能性を保証すると想像してください。 このタイプのデータをある場所から別の場所に転送し、答えを得ることができ、副作用を心配しないと想像してください。 私がリードしている場所がわかりますよね?



関数とデータ型の使用は、可変オブジェクトを使用する一般的なオブジェクト指向アプローチよりも、クライアントとサーバーの相互作用をモデル化するためのよりシンプルで柔軟なアプローチです。



ユーザーはいませんが、おそらくSignupUserがいます。 注文はありませんが、間違いなくPlaceOrderに出くわすでしょう。 また、Managerで終わるクラスが表示されたら、逃げてください。



どのような選択肢がありますか?



私は、現代のオブジェクト指向の世界で最も深刻なエラーの1つは次のとおりであると信じています。



「オブジェクト指向言語を使用しているため、ORMが必要です」



ほんと? 実はいや! 必要なのは、データベースおよびデータ変換レイヤーからデータを取得して、データドメインデータ型を永続性互換型に簡単に変換できるようにする方法です。



これにより、典型的なORMに現れる不必要な抽象化の束が排除されます。



オブジェクトを使用してクライアントとサーバー間の相互作用をモデル化できますが、可変オブジェクトを扱う必要はありません。



これをサポートするオブジェクト指向言語は長生きします。



私のRubyプログラミングスタイルは、ここ数年で劇的に変化しました。 ORMを取り除くことは、私がこれまでに行った中で最高の決断の1つでした。 したがって、私はRuby Object Mapperに取り組み、会議でそれについて話します。 おそらくこれは一般に受け入れられている意見に反しているかもしれませんが、一般的に受け入れられ、習慣的に常に失敗する場合、問題を掘り下げ続ける理由はありません。 どれだけ深く登れるのか知りたくありません。



実際には、機能的なコミュニティはオブジェクト指向の同僚よりも先を行っています。 私たちができる最善のことは、機能プログラミングの世界からどのような主要なパラダイムを取得して、オブジェクト指向コードに適用して利益を得ることができるかを理解することです。 私にとって、それはORMと可変オブジェクトを放棄することです。



ORMをあきらめます。 一貫した設計を受け入れます。 うまく機能します。



翻訳:ナタリアベース



All Articles