2012-05-27 69 views
3

我有一个对象:库存储库模式的域模型

一个库可以有多个Books,CD和Papers。除具有Address属性的Library类外,每个类都有Id,Name和Price属性。

我想创建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()方法。

请指导。

+0

看看这篇文章从MSDN领域驱动设计http://msdn.microsoft.com/en -us /杂志/ dd419654.aspx。文章讨论了很多这些问题,并链接到其他相关信息。您不应为每个对象创建一个存储库,而应为每个“聚合”创建一个存储库。构成逻辑实体的对象组。 –

+0

我认为使用一些ORM会更好。您可以随时更改基础数据提供者。例如,NHiberante可以将数据存储在CSV文件中(检查此问题http://stackoverflow.com/questions/680994/can-nhibernate-persist-to-flat-files-instead-of-database)。 –

回答

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(); 
     } 
    } 
}