具有存储库模式的域模型

时间:2012-05-27 13:00:14

标签: c# java .net oop architecture

我有一个对象:图书馆

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

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

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

稍后我们考虑将其存储在数据库中。然后我们将有一个图书馆桌子,一张书桌,一张CD桌子和一张纸桌。

用户在屏幕上创建一个库对象,然后在屏幕上创建书籍,CD和纸张。

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

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

在这种情况下,我希望上面的其他层保持不变。我希望LibraryRepository.Save()能够注意它是否需要使用XML或CSV或DB。 我很困惑如何创建一个Repository模式来解决LibraryRepository.Save()方法。

每个人都说Repository类应该承担一个责任。 它应该只保存一个对象类型,不应该取一个对象,取其相关的类并保存它们。每个类都应该有自己的Repository类。

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

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

请指导。

1 个答案:

答案 0 :(得分:2)

由于存储库是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();
        }
    }
}