I'm fiddling with an MVC framework, and I stumbled upon a problem I'm not sure how to solve.
I want to make a DomainObjectFactory
for the Model layer of my application, however, each Domain object would have a different set of arguments, for instance:
- Person - $id, $name, $age.
- Post - $id, $author, $title, $content, $comments
- Comment - $id, $author, $content
And so on. How can I easily tell my factory what kinds of object do I require?
I've came up with several options:
- Pass an array - I dislike this one, because you can't rely on the constructor's contract to tell what the object needs for his work.
- Make the
DomainObjectFactory
an interface, and make concrete classes - Problematic, because that's an awful lot of factories to make!
- Use Reflection - Service locator much? I don't know, it just seems that way to me.
Is there a useful deign pattern I can employ here? Or some other clever solution?
Why do you want to initialize a Domain Object with all the properties assigned?
Instead just create an empty Domain Object. You might in the factory check, if it has prepare()
method to execute. Oh .. and if you are using DAO, instead of directly interacting with Mappers, you might want to construct and inject the appropriate DAO in your Domain Object.
The assignment of values should just happen in the Service. By the use of ordinary setters.
Some examples:
Retrieving existing article
public function retrieveArticle( $id )
{
$mapper = $this->mapperFactory->create('Article');
$article = $this->domainFactory->create('Article');
$article->setId( $id );
$mapper->fetch( $article );
$this->currentArticle = $article;
}
Posting new comment
public function addComment( $id, $content )
{
$mapper = $this->mapperFactory->create('article');
$article = $this->domainFactory->create('Article');
$comment = $this->domainFactory->create('Comment');
$comment->setContent( $content );
$comment->setAuthor( /* user object that you retrieved from Recognition service */ );
$article->setId( $id );
$article->addComment( $comment );
// or you might retrieve the ID of currently view article
// and assign it .. depends how you build it all
$mapper->store( $article ); // or
}
Passing user input
public function getArticle( $request )
{
$library = $this->serviceFactory->build('Library');
$library->retrieveArticle( $request->getParameter('articleId'));
}