I'm trying to follow some of the more current design principles including SOLID and Domain Driven Design. My question is around how people handle "Initializing" Domain Objects.
Here's a simple example:
Based on SOLID, I should not depend on concretions, so I create an interface and a class. Since I'm taking advantage of Domain Driven Design, I create an object with relevant methods. (i.e. not anemic).
Interface IBookstoreBook
{
string Isbn {get; set;}
int Inventory {get; set;}
void AddToInventory(int numBooks);
void RemoveFromInventory(int numBooks);
}
public class BookstoreBook : IBookstoreBook
{
public string Isbn {get; set;}
public int Inventory {get; private set;}
public void AddToInventory(int numBooks);
public void RemoveFromInventory(int numBooks);
}
To help with testing and be more loosely coupled, I also use an IoC container to create this book. So when the book is created it is always created empty. But, if a book doesn't have an ISBN and Inventory it is invalid.
BookstoreBook(string bookISBN, int bookInventory) {..} // Does not exist
I could have 4 or 5 different classes that use a BookstoreBook. For one,
public class Bookstore : IBookstore
{
...
public bool NeedToIncreaseInventory(BookstoreBook book) { ...}
...
}
How does any method know is getting a valid book? My solutions below seem to violate the "Tell Don't Ask" principle.
a) Should each method that uses a Bookstore book test for validity? (i.e. should NeedToIncreaseInventory test for a books validity? I'm not sure it should have to know what makes a BookstoreBook valid.)
b) Should I have a "CreateBook" on the IBookstoreBook object and just "assume" that clients know they have to call this anytime they want to initialize a BookstoreBook? That way, NeedToIncreaseInventory would just trust that "CreateBook" was already called on BookstoreBook.
I'm interested in what the recommended appreach is here.