私はほとんどゼロから新しいウェブサイト プロジェクトを書いています。プロジェクトは C# ですが、私のバックグラウンドは PHP です (以下の疑似コードは、簡潔で宣言的であるように努めており、混在している場合があります)。
問題
2 つの場所のいずれかから構成データを取得する必要があります。ローカル データベースから取得する場合もあれば、Soap サービスから取得する場合もあります。どちらのソースからも同じ Model オブジェクトのセットを作成できるはずです。
データは、異なるデータ ソースの完全に異なる構造に格納されます。いくつかの異なる Soap 応答は、Soap 側からつなぎ合わせる必要がありますが、DB 構造は、コードでモデル オブジェクトを構造化する方法に非常に近いものです。
構成は、オブジェクトのツリーで構成されます。製品には、適用時の条件を持つオプションを含むプロパティが含まれます。
目標
可能な限り懸念事項を分離したいと思います (うまくいけば、テスト/保守/拡張機能の両方を容易にするため):
- 私のモデルオブジェクトは、データの永続性または取得について何も知らないはずです
- Data Persistence オブジェクトは、可能な限り、データ ソースの正確なタイプにとらわれないようにする必要があります。
- オブジェクトの作成をできるだけ分離したいと考えています。
質問
私はこれに関するさまざまな設計パターンを認識しています (ただし、それらを完全に理解しているかどうかは完全にはわかりません)。Programmersについてこれと同様の質問をしたところ、 Persistence Ignorance (詳細はこちら) とRepositoryパターンに関する回答がありました。どちらも Microsoft の世界の概念のようです。
私が知る限り、「Persistence Ignorance」は単に、データ ストレージ メカニズムについて何も知らない Model オブジェクトを持つという概念であり、Repository パターンは Data Mapper パターンと非常によく似ているように見えますが、ファサードのようなものである可能性があります。実際に起こっていることの多くを隠します。
だから私の質問は:
Data Mapper パターンでは、Model オブジェクトごとに 1 つの Mapper が必要ですか? 構成ツリー全体に 1 つではなく?
したがって、これらすべての Mapper オブジェクトを使用する構成ツリー構築オブジェクトが必要でしょうか?
class ConfigBuilder() {
public ConfigBuilder (productMapper, propertyMapper, optionMapper, conditionMapper) {
// save them into local properties
}
public Products() {
var products = productMapper.FetchAll();
foreach (var product in products) {
AddProperties(product);
}
return products;
}
private AddProperties(products) { /* ... */ }
private AddOptions(property) { /* ... */ }
private AddConditions(option) { /* ... */ }
}
これは良い解決策のように思えますか?
オブジェクトを構築するロジックはどこに配置する必要がありますか?
ある時点で、Soap サービスから取得した XML データのランダムな配列から構成オブジェクトを構築するためのかなりの量のロジックと、データベースから同じことを行うための少量のロジックが必要になります。
Mapper オブジェクトの別のインスタンスにオブジェクトを構築するロジックを配置する必要がありますか?
interface IProductMapper { FetchAll; FetchByCode; Create; Delete; Update }
class ProductMapperXml implements IProductMapper {
public ProductMapperXml(xmlDataSource) {}
public FetchAll() { /* A whole bunch of logic to create the Product objects from XML data source */ }
}
class ProductMapperDatabase implements IProductMapper {
public ProductMapperDatabase(databaseConnection) {}
public FetchAll() { /* Select and build products from the database */ }
}
これでいいですか?このロジックをさらに抽象化する必要がありますか? もしそうなら、なぜですか?ProductMapperXml
また、オブジェクト自体がかなりのロジックを持ち、Product
内部でオブジェクトを作成する責任も負っていることに少し不安があります。私はそれProductFactory
を何らかの形で渡す必要がありますか?それともファクトリメソッドを使用しますか?
私の提案よりもこれを解決するエレガントな方法があるかどうか教えてください。また、見逃した抽象化またはデザインパターンのレイヤーがあれば、それから恩恵を受けることができますか?