0

私は実例に抽象化しようとする現実世界の問題を抱えています。

親オブジェクトが子にアクセスでき、子が親にアクセスできるツリーにデータ オブジェクトがあるとします。

// Interfaces
interface IParent<TChild> { List<TChild> Children; }
interface IChild<TParent> { TParent Parent; }

// Classes
class Top : IParent<Middle> {}
class Middle : IParent<Bottom>, IChild<Top> {}
class Bottom : IChild<Middle> {}

// Usage
var top = new Top();
var middles = top.Children; // List<Middle>
foreach (var middle in middles) {
    var bottoms = middle.Children; // List<Bottom>
    foreach (var bottom in bottoms) {
        var middle = bottom.Parent; // Access the parent
        var top = middle.Parent; // Access the grandparent
    }
}

3 つのデータ オブジェクトはすべて、2 つのデータ ストア (データベースと Web サービスなど) に永続化されるプロパティを持ち、ストアを反映して同期する必要があります。一部のオブジェクトは Web サービスからの要求のみを行い、一部のオブジェクトは Web サービスへの書き込みのみを行います。

データマッパー

データ アクセスの私のお気に入りのパターンはData Mapperです。これは、データ オブジェクト自体をデータ ストアとの通信から完全に分離するためです。

class TopMapper {
    public Top FetchById(int id) {
        var top = new Top(DataStore.TopDataById(id));
        top.Children = MiddleMapper.FetchForTop(Top);
        return Top;
    }
}

class MiddleMapper {
    public Middle FetchById(int id) {
         var middle = new Middle(DataStore.MiddleDataById(id));
         middle.Parent = TopMapper.FetchForMiddle(middle);
         middle.Children = BottomMapper.FetchForMiddle(bottom);
         return middle;
    }
}

このようにして、データ ストアごとに 1 つのマッパーを用意し、必要なマッパーからオブジェクトを構築し、必要なマッパーを使用してそれを保存することができます。

ここには循環参照がありますが、ほとんどの言語はオブジェクトへのメモリ参照を格納できるため、実際には無限のデータは存在しないため、問題にはならないと思います。

Topこれに関する問題は、新しい、Middleまたはを構築するたびに、そのオブジェクトのまたはプロパティBottom内にオブジェクト ツリー全体を構築する必要があり、それに伴うすべてのデータ ストア要求とメモリ使用量が必要になることです。そして実際には、私のツリーはここに示されているものよりもはるかに大きいので、これは問題です。ParentChildren

オブジェクト内のリクエスト

この場合、オブジェクトはParentChildrenそれ自体を要求します。

class Middle {
    private List<Bottom> _children = null; // cache
    public List<Bottom> Children {
        get {
            _children = _children ?? BottomMapper.FetchForMiddle(this);
            return _children;
        }
        set {
            BottomMapper.UpdateForMiddle(this, value);
            _children = value;
        }
    }
}

これはリポジトリ パターンの例だと思います。あれは正しいですか?

この解決策は素晴らしいようです。データは、必要なときにのみデータ ストアから要求され、その後、再度要求する場合はオブジェクトに格納され、それ以上の要求を回避します。

ただし、2 つの異なるデータ ソースがあります。データベースはありますが、Web サービスもあります。Web サービスからオブジェクトを作成し、それをデータベースに保存してから、データベースから再度要求し、Web サービスを更新できる必要があります。

データ オブジェクト自体がもはやデータ ソースを認識していないわけではないので、これは私を不安にさせます。循環依存は言うまでもなく、新しい依存関係を導入したため、テストが難しくなっています。また、オブジェクトはデータベースとの通信をマスクします。

その他のソリューション

複数の店舗の問題を処理できるが、毎回すべてのデータを構築/要求する必要がないことを意味する他のソリューションはありますか?

4

1 に答える 1

0

あなたは本当に2つの無関係な問題について尋ねています。はい、リポジトリ パターンは、アイテム自体 (エンティティ) がストアについて何も知らないストアからアイテムを抽出する必要があります。したがって、通常、CRUD を実装するリポジトリがあり、エンティティが必要になるたびにそこから取得します。マッパーの要点がわかりません。また、なぜその中流階級が必要なのかもわかりません.. ?

2 番目の質問は、一度に作成されたわけではない大きなツリーをどのように処理するかです。これにデザインパターンでフラグを立てたので、ツリークラスがCompositeを実装し、「マッパー」の代わりにBuilderを持つ必要があることを提案するのが適切です。次に、そのビルダーは段階的に物事を構築できる必要があります。それは興味深い問題です。依存性注入の世界では、これはOpenSessionInViewによってさらに複雑になります。

単なる位置の区別のためのクラスを持たないバージョンについて考えてみてください。Composite はそれを可能にすると思います。

于 2012-10-30T15:13:08.393 に答える