2

オブジェクトのタイプに基づいて、オブジェクトに対していくつかの操作 (db 永続化、json シリアル化など) を実行したいと考えています。ポリモーフィズムはこれを行うための通常の方法ですが、モデルにビジネス以外のロジックを多く追加したくありません。

これは単純な型階層です (これらは私のオリジナルの型ではありませんが、問題を示すために単純化したものです):

public abstract class Book
{
    public int Id { get; set; }
    public string Title { get; set; }
}

public class PrintBook : Book
{
    public decimal Weight { get; set; }
    public CoverType CoverType { get; set; }
}

public class Ebook : Book
{
    public EbookType Type { get; set; }
    public bool AutoUpgrade { get; set;}
}

これらの書籍はクライアント側で JS オブジェクトとして作成され、JSON としてサーバーに送信され (構造を変更することはできません)、書籍のリストに解析されます。

public List<Book> ParseJson(string json)
{
    /* JSON sample (in JS we have duck typing - the type is determined by its members)
    "books": [
        { "id": 1, "title": "Sample print book", "weight": 50, "coverType": "soft" },
        { "id": 2, "title": "Sample ebook", "type": "pdf", "autoUpgrade": true }
    ]
    */
}

次に、このリストをデータベースに保存します。

public void SaveBooksToDatabase(List<Book> books)
{
    foreach (var book in books)
    {
        if (book is Ebook)
        {
            Save((Ebook)book);
        }
        else if (book is PrintBook) 
        {
            Save((PrintBook)book);
        }
    }
}

public void Save(Ebook ebook) { /* */ }

public void Save(PrintBook printBook) { /* */ }

私は、SaveBooksToDatabase メソッドでのタイプのディスパッチに満足していません。これは、Open-Closed Principle に違反しており、新しいタイプを追加するときにあまり安全ではありません。

しかし、ブック階層に抽象的な Save() メソッドを追加したくありません。保存以外にも型に依存する操作 (json シリアル化など) があり、これは単一責任の原則に違反するからです。訪問者パターンが代替ソリューションと見なされる可能性があることは知っていますが、IMO では、より厄介なボイラープレート コードが導入されます。

そのような場合を処理するための最良かつ最もエレガントな方法は何ですか?

4

1 に答える 1

2

クライアントから送信されたオブジェクトと、自分自身を保存する方法を知っているビジネス オブジェクトを分離します。

JSON からデシリアライズできるクラスが 1 つあります。

次に、継承階層を持つBook、、、のような複数のビジネス クラスを作成します。これらには、とりわけポリモーフィックメソッドがあります。PrintBookEBookSave

AutoMapperのようなツールを使用して、データ転送オブジェクトとビジネス オブジェクトをマッピングします。

于 2014-12-18T22:02:10.313 に答える