【问题标题】:Dispatching on type vs polymorphism in C#. The business entities and non-business logicC# 中类型与多态性的调度。业务实体和非业务逻辑
【发布时间】:2014-12-18 17:49:03
【问题描述】:

我想根据对象的类型对对象执行一些操作(数据库持久性、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 方法中的类型调度不满意:它违反了开闭原则,并且在我们添加新类型时不是很安全。

但我不想在书籍层次结构中添加抽象的 Save() 方法,因为除了保存之外还有更多类型相关的操作(例如 json 序列化),这将违反单一责任原则。我知道访问者模式可能被认为是一种替代解决方案,但 IMO 会引入更多混乱的样板代码。

处理此类情况的最佳和最优雅的方法是什么?

【问题讨论】:

  • 我看不出这与 DDD 有什么关系。
  • 也许它与 DDD 并不严格相关,但示例书籍层次结构可以被认为是域对象(如果我们决定将更多逻辑放入其中)或普通 poco(就像现在一样)。问题是 - 如何以及在哪里放置这种“不那么商业”的逻辑。

标签: c# design-patterns single-responsibility-principle open-closed-principle


【解决方案1】:

我会在客户端发送的对象和知道如何保存自己的业务对象之间保持分离。

我会有一个可以从 JSON 反序列化的类。

然后,我将拥有多个业务类,例如 BookPrintBookEBook,以及继承层次结构。这些将具有多态 Save 方法等。

我会使用AutoMapper 之类的工具在数据传输对象和业务对象之间进行映射。

【讨论】:

    猜你喜欢
    • 2013-09-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-18
    • 2012-03-08
    • 2015-11-07
    • 2011-04-15
    • 2013-11-29
    相关资源
    最近更新 更多