简体   繁体   中英

Domain Model with Repository Pattern

I have an object: Library

One library can have multiple Books, CDs and Papers. Each class has Id, Name and Price property except Library class that has Address property.

I want to create Repository pattern to abstract where the data is stored from the layers above. Right now, data is stored in xml files.

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

Later on we are thinking of storing it in databases. We will then have a library table, a books table, a cd table and a papers table.

User creates a library object on the screen and then creates books, cds and papers on the screen.

He then clicks on Save. At that point, I want to take the newly created library object and save it in XML so I want to have Repository and using dependency injection, I will inject an implementation of xml repository in the layers above so data is stored into correct place. I can serialize the Library object and get xml and call simple Save method to save the library object.

but imagine then I replace XMLRepository with DatabaseRepository.

In that case, I want the rest of the layers above to remain unchanged. I am hoping that LibraryRepository.Save() will take care whether it needs to go in XML or CSV or DB. I am confused how I will create a Repository pattern to solve LibraryRepository.Save() method.

Everyone everywhere says that Repository class should have a single responsibility. It should only save one object type and shouldn't take an object, take its related classes and save them too. Each class should have its own Repository class.

Also each library object has multiple Books objects. I don't want to use a for loop and go through each book in LibraryRepository.Save method.

I am not sure how I should create my domain model and call the Library Save() method.

Please guide.

As repository is an abstraction of persistency for your BL, use repository interface.

Each repository implementation should take care of object structure mapping to data storage, or use specific mappers. BL/Service classes would work with repository via interface, without knowledge of internal implementation of a particular repository.

So you'd have something like

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

And several implementations

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM