2

データモデルを保存するための優れた設計を考え出そうとしています。言語はPythonですが、これはかなり不可知論者だと思います。

現時点では、3つの可能な戦略を想定しています。

オブジェクトデータベース

データモデルはオブジェクトのネットワークです。それらを作成するとき、永続オブジェクトの子孫として指定します。例:

class Tyres(PersistentObject):
    def __init__(self,brand):
        self._brand = brand

class Car(PersistentObject):
    def __init__(self,model):
        self._model = model
        self._tyres = None
    def addTyres(self,tyres):
        self._tyres = tyres
    def model(self):
        return model

クライアントコードは永続性を認識せず、メモリ内にあるようにオブジェクトを操作し、永続性オブジェクトはクライアントコードが知らないうちにすべてを処理します。取得は、データベースオブジェクトのキー付きルックアップを介して実行できます。これは、(他の多くの中で)ZopeObjectDatabaseが使用するアプローチです。利点は、遅延検索であり、変更は、変更されたオブジェクトでのみ操作され、変更されていないオブジェクトは取得されません。

棚のオブジェクト

上記のデータモデルはメモリで表されますが、データベースを使用してデータをモノリティックエンティティとしてプッシュまたはプルします。例えば:

 car = Car("BMW")
 tyres = Tyres("Bridgestone")
 car.setTyres(tyres)
 db.store(car)

これは、ピクルスベースのソリューションが行うことです。これは、ある意味で前のソリューションと似ていますが、オブジェクトを単一のバンドルとして保存し、それを単一のバンドルとして再度取得する点が異なります。

ファサード

便利なメソッドを持つ単一のデータベースクラス。クライアントコードはオブジェクトを処理せず、IDのみを処理します。例

class Database:
     def __init__(self):
         # setup connection

     def createCar(self, model):
         # creates the car, returns a numeric key car_id

     def createTyresForCar(self, car_id, brand):
         # creates the tyres for car_id, returns a numeric id tyres_id

     def getCarModel(self, car_id):
         # returns the car model from the car identifier
     def getTyresBrand(self, car_id, tyre_id):
         # returns the tyre brand for tyres_id in car_id.
         # if tyres_id is not in car_id, raises an error.
         # apparently redundant but it's not guaranteed that
         # tyres_id identifies uniquely the tyres in the database.

この解決策はかなり物議を醸しています。データベースクラスには多くの責任がありますが、これがSOAPで使用されている哲学であると感じています。オブジェクトを直接操作するのではなく、リモートサーバーへのオブジェクトプロパティの照会を実行します。SQLがない場合、これはリレーショナルデータベースへのインターフェイスになる可能性があります:db.createTable()、、。SQLはこれを単純化して、言語(SQL)の解析と実行を犠牲にして、非常に単純なdbインターフェースを取得します。他の部分に触れることなく、関心のあるデータモデルのサブパートを操作することができます。db.insert()db.select()db.query(sql_string)

3つのデザイン、特に3つ目のデザインについてご意見をお聞かせください。良いデザインはいつですか?

逆論理

これは私がMediaWikiコードで見たものです。のようなものを持つ代わりに

 db.store(obj)

彼らは持っている

 obj.storeOn(db)

編集:私が示すサンプルデータモデルは少し単純です。私の本当の目的は、グラフベースのデータモデルを作成することです(誰かがプロジェクトに参加したい場合は、私は光栄に思います)。3番目のソリューションで私が心配しているのは、(メモリ内のデータモデルではなく)書き込まれたデータモデルを強力にカプセル化し、バックエンドをマスクすることですが、すべてのメソッドが公開されている中央クラスは1つしかないため、爆発するリスクがあります。正直なところ、3番目のケースは好きではありませんが、考えられる解決策として考えたので、質問の皿に載せたかったのです。そこに良いものがあるかもしれません。

編集2:反転論理エントリを追加しました

4

2 に答える 2

1

最初の設計は、ドメイン駆動設計と最も互換性があります。実装の永続性をオブジェクトに対して完全にプライベートにするということは、そのリレーショナル表現に関係なくオブジェクトを使用できることを意味します。オブジェクトにとっては、低レベルのCRUD操作ではなく、ドメイン固有の動作に関連するメソッドを公開する場合にのみ役立ちます。高レベルのメソッドは、そのオブジェクトのコンシューマーに提供したい唯一のAPIコントラクトです(つまり、誰もが車を削除できるようにしたくない)。複雑なデータ関係を実装し、それらを1か所でのみコーディングできます。

2番目のデザインは、 Visitorパターンで使用できます。車のオブジェクトは、永続化する必要のある部分を認識していますが、データベースへの接続はありません。したがって、carオブジェクトをデータベース接続インスタンスに渡します。内部的に、dbは与えられたオブジェクトを呼び出す方法を知っています。おそらく、車はいくつかの「db-callable」インターフェースを実装しています。

3番目の設計は、アダプターパターンの実装に役立ちます。すべてのデータベースブランドのAPIは異なり、SQLのすべてのフレーバーはわずかに異なります。プレーンなデータベース操作に対する汎用APIがある場合は、それらの違いをカプセル化し、それぞれのブランドのデータベースと通信する方法を知っている別の実装を交換できます。

于 2009-08-23T05:57:46.497 に答える
0

あなたの例は明らかに考案されているので、言うのは難しいです。

データモデルが変更される頻度に基づいて決定を下す必要があります。IMHOの車は、新しい部品を集めることはあまりありません。したがって、モデル化するすべてのアイテムのデータベース内の静的モデルを使用し、次にそれらすべてをリンクするテーブルを使用しますが、実際に行っていることには誤りがある可能性があります。

モデル化する必要のある実際のデータについて、私たちに相談することをお勧めします。

于 2009-08-23T05:52:55.773 に答える