0

「ウィジェット」を含むデータベースがあるとしましょう。ウィジェットには、たとえば長さや幅などのプロパティがあります。wdigets を作成するための元の下位レベルの API はごちゃごちゃしているので、呼び出し元が簡単に操作できるように上位レベルの関数セットを作成しています。データベースは奇妙で、ウィジェット オブジェクトの作成のタイミングをうまく制御できません。具体的には、他の特定のことが最初に発生した後、処理の後の段階まで作成できません。しかし、ウィジェット オブジェクトが初期段階で作成されていると呼び出し元に考えてもらいたいので、最初からそのプロパティを取得/設定できます。

そこで、呼び出し元が操作できる「ProxyWidget」オブジェクトを実装しました。目的の値を格納できる private_Length や private_Width などのプライベート フィールドがあります。次に、呼び出し元がアクセスできるパブリック プロパティの Length と Width もあります。発信者が Width プロパティの値を設定するように指示した場合、ロジックは次のようになります。

  • 対応するウィジェット オブジェクトがデータベースに既に存在する場合は、その Width プロパティを設定します。
  • そうでない場合は、後で使用するために、指定された幅の値を private_Width フィールドに保存します。

後の段階で、ウィジェット オブジェクトがデータベースに作成されたことを確認したら、すべての値をコピーします。private_Width からデータベースの Width フィールドなどにコピーします (残念ながら、一度に 1 つのフィールド/プロパティ)。 .

これは、1 つのタイプのウィジェットで問題なく機能します。しかし、私は約 50 の型を持っており、それぞれに約 20 の異なるフィールド/プロパティがあり、これは維持できない混乱につながります。よりスマートなアプローチがあるかどうか疑問に思っています。おそらく、リフレクションを使用して「プロキシ」オブジェクトを作成し、フィールド/プロパティ データを一般的な方法でコピーできますか? どういうわけか共通コードを除外しますか? 「データ バインディング」パターンから何かを学べますか? 私はプログラマーではなく数学者であり、現在の私のアプローチはまったくばかげているのではないかと不安に思っています。私のコードはC#です。

4

1 に答える 1

1

まず、私の経験では、データ アクセス レイヤーを手動でコーディングすることは、多くの反復作業のように感じる可能性があり (NHibernate や Entity Framework などの ORM を配置すると、この問題多少緩和される可能性があります)、レガシー データ アクセス レイヤーの更新ひどいものです。特に多くの部分で構成されている場合は機能します。

ご質問で不明な点もありますが、ハイレベルな回答は可能だと思います。これらは、いくつかのアイデアを提供することを目的としています。

  • ProxyWidgetの代替実装 (または既存の低レベル API のウィジェット クラスが呼び出されるもの) として構築するかWidget、「上に」または「ラッパー アラウンド」として実装することができますWidget。これがアダプターの設計パターンです。

    public sealed class ExistingTerribleWidget { … }
    
    public sealed class ShinyWidget // this is the wrapper that sits on top of the above
    {
        public ShinyWidget(ExistingTerribleWidget underlying) { … }
        private ExistingTerribleWidget underlying;
        … // perform all real work by delegating to `underlying` as appropriate  
    }
    

    (少なくとも既存の低レベル API を使用するコードがまだある間は) 完全に別のWidget実装を作成する代わりに、このパターンを使用することをお勧めします。データベース スキーマが変更された場合は、2 つの異なる API を更新する必要があるためです。 . 新しいクラスを既存の API の上にラッパーとして構築する場合EasyWidget、それは変更されないままであり、基礎となる実装のみを更新する必要があります。

  • 2つの機能があると説明ProxyWidgetしています(1)すでに永続化されているウィジェットへの変更を許可します。(2)後でデータベースに追加される新しいウィジェットのバッファ。

    1 つの共通の基本型と 2 つのサブクラス (まだ永続化されていない新しいウィジェット用と、既に永続化されたウィジェット用) があれば、おそらく設計を簡素化できます。後者のサブタイプにはID、既存のウィジェットをデータベースで識別、ロード、変更、および更新できるように、追加のデータベース プロパティがある可能性があります。

    interface IWidget { /* define all the properties required for a widget */ }
    
    interface IWidgetTemplate : IWidget
    {
        IPersistedWidget Create();
        bool TryLoadFrom(IWidgetRepository repository, out IPersistedWidget matching);
    }
    
    interface IPersistedWidget : IWidget
    {
        Guid Id { get; }
        void SaveChanges();
    }
    

    これはBuilder デザイン パターンの一例です。

  • 多くのクラス (たとえば、50 以上のデータベース オブジェクト タイプ) に対して同様のコードを記述する必要がある場合は、T4 テキスト テンプレートの使用を検討できます。これにより、コードの記述の繰り返しが少なくなります。ただし、50 以上のオブジェクトをどこかに定義する必要があります。

于 2013-03-30T11:12:27.390 に答える