2009-08-14 31 views
2

私は、古いVB6 UI/COBOLデータベースアプリケーションを現代に改造するチームの一員です。私が雇われる前に、データベースの前にUIをやり直すという決定が下されました(主に売り上げ、私は確信しています)。ですから、今はWPFとMVVMを使って大きな効果を上げています。これまでのところ、特にModelレイヤーとしてCSLAを使用するのは素晴らしいことです。C#CSLAビジネスオブジェクトのジレンマ:読み取り専用vs読み込み/書き込み

ただし、私たちの開発は古い製品の次のバージョンと並んでいるため、少し拘束されています。 COBOLデータベースへの呼び出しに対しては、変更(または最小限の変更)を行うことはできません。これまでのところ、SQL Serverの栄光の日々を信じることができます。

私はBOデザインに関して特に厄介なロードブロッキングを打ちましたが、リストに返された "軽い"ビジネスオブジェクトとその "完全な"対応を扱っています。例を試してみましょう:

人のオブジェクトがDBに複数のフィールドを持っているとしましょう。そのテーブルを検索すると、すべてのフィールドが返されるわけではないので、私たちはライトオブジェクトにこれらのフィールドを設定します。これらのフィールドは、完全な人のサブセットであってもなくてもよい。私たちは、検索に特有の他の情報を検索するために、1つまたは2つのジョインを行っている可能性があります。しかし、personオブジェクトを編集したい場合は、フルバージョンを取得してUIを生成するために別の呼び出しを行う必要があります。これは、私たちに2つのオブジェクトを残し、削除、編集、追加した後の親オブジェクトに個人リストを同期させようとしている間に、1つのVMでその状態をゆがめようとしています。もともと、私はライトオブジェクトをReadOnlyBase <>から派生させました。しかし、今では半分の半分、半分の半分を除いて完全なBOのリストを持つ同じリストの振る舞いを扱っているので、私はちょうどLiteとフルバージョンの両方をBusinessBase < >単にライト版のセッタープロパティをプライベートにしました。

他に誰かが出てきてこれに対する解決策を見つけましたか?それを眠った後、私はこの潜在的な解決策を思いついた。私たちはこのように、別のBOで私たちのBOのフルとliteのバージョンを包む場合:

public class PersonFull : BusinessBase<PersonFull> 
{ 
    ... 
} 
public class PersonLite : BusinessBase<PersonLite> 
{ 
    ... 
} 

public class Person : BusinessBase<Person> 
{ 
    public PersonFull PersonFull; 
    public PersonLite PersonLite; 
} 
public class PersonList : BusinessListBase<PersonList, Person> 
{ 
} 

明らかにすべてがCSLA登録プロパティと、そのようなことだろうが、簡潔にするために、彼らはそこにフィールドです。この場合、PersonとPersonListはすべてのファクトリメソッドを保持します。検索操作の後、PersonListにPersonLiteメンバーがすべて入力され、PersonFullオブジェクトがすべてnullだったPersonオブジェクトによってPersonListが作成されます。完全なバージョンを取得する必要がある場合は、単にPersonオブジェクトにそのように指示して、今はPersonFullオブジェクトを持っているので、編集UIを設定できます。 Personオブジェクトを削除する場合は、リスンしているすべてのVMでリストの整合性を維持しながら、CSLAの削除プロシージャを使用して簡単に行うことができます。

私はこれが誰にとっても意味をなさないことを願っています。誰かが違う解決策を持っていれば、彼らはこれを成功裏に批判しています。

ありがとうございます!

(から再掲:http://forums.lhotka.net/forums/thread/35576.aspx

答えて

-1

あなたはCSLAフレームワークが付属してロッキーの例上で見れば、彼は常に、読み取り専用、読み取り/書き込みオブジェクトからオブジェクトを分離することがわかります。私はこれが正当な理由で行われたと思います。なぜなら、その振る舞いは大きく異なるためです。読み込み専用のオブジェクトは、よりパフォーマンスに基づいており、その検証は非常に異なり、通常はあまり情報がありません。読み取り/書き込みオブジェクトはパフォーマンスベースではなく、検証、承認などに大きく依存します。

しかし、それはあなたが現在自分で見つけたジレンマを残します。私がすることは、各クラスのコンストラクタをオーバーロードして、お互いに渡して、必要なものを互いにコピーすることができるようにすることです。このような

何か:

public class PersonLite : BusinessBase<PersonLite> 
{ 
    public PersonLite(PersonFull fullPerson) 
    { 
     //copy from fullPerson's properties or whatever 
    } 
} 

public class PersonFull : BusinessBase<PersonFull> 
{ 
    public PersonFull(PersonLite litePerson) 
    { 
     //copy from litePerson's properties or whatever 
    } 
} 

はあなたにも工場出荷時のパターンでこれを行うことができ、私は信じているロッキーの好みです。

+0

私は、あなたが提案しているものが解決すべきものであるかどうかは完全にはわかりません。ライトBOは、ライト版からのユニークなデータで完全なBOを水和するためにDBに行くことができるので、完全なBOを決して投入することはありません。私は編集後にライトバージョンを更新するフルバージョンを見ることができたと思うが、これは本当にそれについて行く方法ではない。 – opedog

+0

ライト版は、完全版を完全に埋め込むことはできませんが、ユーザーに表示され、残りのデータが遅延ロードされるように十分である可能性があります。私はこれまでいくつかの成功を収めてきました。メモリオブジェクトを修正しようとしているなら、これに対するあなたのアプローチは全く異なるでしょう。 – Joseph

+0

フロントエンドが完了した時点でバックエンドBOを再構築する予定であれば、すべてのプロパティを含む新しいCSLAオブジェクトから開始するテストケースとして使用してみましょう。 –

3
public class PersonLite : ReadOnlyBase<PersonLite> 
{ 
    public void Update(PersonFull person) { } 
} 

public class PersonFull : BusinessBase<PersonFull> 
{ 
    // blah blah 
} 

私は「完全な」オブジェクトに対して行われた変更で「ライト」オブジェクトを更新し、ReadOnlyBaseとしてそれを残すだろう。 ReadOnlyBaseの "ReadOnly"は、データベースから読み取られ、保存されていないオブジェクトを意味することを覚えておくことが重要です。よりエレガントではありませんが、より正確な名前はNotSavableBaseです。そのようなオブジェクトにはフェッチ以外のもののDataPortal_XYZ機構がないためです。明白な理由から、そのようなオブジェクトは通常不変のプロパティを持ちますが、それらは必要ありません。 ReadOnlyBaseCore.BindableBaseから派生し、INotifyPropertyChangedを実装しています。したがって、そのプロパティの値を変更すると、バインディングでうまく動作します。

"フル"オブジェクトを保存すると、新しく保存されたインスタンスがリストにあるインスタンスのUpdate(PersonFull)メソッドに渡され、 "フル"オブジェクトから "ライト"オブジェクトのプロパティが更新されます。

私はこのテクニックを何度も使ってきましたが、うまくいきます。

関連する問題