【问题标题】:Domain Model with Repository Pattern具有存储库模式的域模型
【发布时间】:2012-06-02 04:50:29
【问题描述】:

我有一个对象:图书馆

一个图书馆可以有多本书籍、CD 和论文。除了具有 Address 属性的 Library 类之外,每个类都有 Id、Name 和 Price 属性。

我想创建存储库模式以从上面的层抽象数据的存储位置。现在,数据存储在 xml 文件中。

<library>
<books></books>
<cds></cds>
<papers></papers
</library>

稍后我们正在考虑将其存储在数据库中。然后我们将有一个图书馆桌、一个书桌、一个 CD 桌和一个文件桌。

用户在屏幕上创建一个图书馆对象,然后在屏幕上创建书籍、CD 和论文。

然后他点击保存。那时,我想获取新创建的库对象并将其保存在 XML 中,因此我想要存储库并使用依赖注入,我将在上面的层中注入 xml 存储库的实现,以便将数据存储到正确的位置。我可以序列化库对象并获取 xml 并调用简单的 Save 方法来保存库对象。

但想象一下,我将 XMLRepository 替换为 DatabaseRepository。

在这种情况下,我希望上面的其余层保持不变。我希望 LibraryRepository.Save() 会照顾它是否需要进入 XML、CSV 或 DB。 我很困惑如何创建一个存储库模式来解决 LibraryRepository.Save() 方法。

世界各地的每个人都说 Repository 类应该有一个单一的职责。 它应该只保存一种对象类型,不应该获取一个对象,获取它的相关类并保存它们。每个类都应该有自己的 Repository 类。

每个库对象也有多个 Books 对象。我不想使用 for 循环并在 LibraryRepository.Save 方法中浏览每本书。

我不确定我应该如何创建我的域模型并调用 Library Save() 方法。

请指导。

【问题讨论】:

  • 我认为最好使用一些ORM。您可以根据需要更改基础数据提供者。例如,NHiberante 可以将数据存储在 CSV 文件中(检查这个问题stackoverflow.com/questions/680994/…)。
  • 看看这篇来自 MSDN msdn.microsoft.com/en-us/magazine/dd419654.aspx 的关于域驱动设计的文章。这篇文章讨论了很多这些问题,并链接到其他相关信息。您不应该为每个对象创建一个存储库,而是为每个“聚合”创建一个存储库。构成逻辑实体的一组对象。

标签: c# java .net oop architecture


【解决方案1】:

由于存储库是 BL 持久性的抽象,因此请使用存储库接口。

每个存储库实现都应该处理到数据存储的对象结构映射,或者使用特定的映射器。 BL/Service 类将通过接口与存储库一起工作,而无需了解特定存储库的内部实现。

所以你会有类似的东西

class LibraryService {
    public LibraryService (ILibraryRepository repo) {} 
    public DoSomeWork(somedata) {
        Library lib = repo.Load(somedata.libid);
        ....
        repo.Save(lib);
    }
}

还有几个实现

class DBLibraryRepository : ILibraryRepository {
    public Save(Library lib) {
        //hibernate session 
        //and you'll have mapping defined for all entities
        //and relations between library and stuff, so books are saved automatically
        _session.Save(lib)
    }
}

class XMLLibraryRepository : ILibraryRepository {
    public Save(Library lib) {
        //serialized does all the work, so no additional loops here
        var xml = Serialize(lib);
        SaveToFile(xml);
    }
}

class CSVLibraryRepository : ILibraryRepository {
    public Save(Library lib) {
        //for example, save library to lib.csv, books - to books.csv.
        //add mappers to do real work, but we'd take care of separation 
        //of books and library manually.
        // (in case of ORM - it has own mappers, 
        //  for XML - serializator is mapper itself)
        var data = LibraryCSVDataMapper.Map(lib);
        data.Save();
        foreach(var book in lib.Books){
            data = BookCSVDataMapper.Map(book);
            data.Save();
        }
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-07-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多