Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

I'm trying really hard to refactor some of my legacy code in the project using best practices and design patterns + DDD so I'd love some feedback on an issue I'm currently having.

Let's assume that I have two entity classes:

class Dog
{
    protected $name;

    function __construct($name)
    {
        $this->name = $name;
    }

    /**
     * @return mixed
     */
    public function getName()
    {
        return $this->name;
    }

    function bark()
    {
        echo 'Rawr';
    }
}

class Husky extends Dog
{
    /**
     * @var Sledge
     */
    protected $sledge;

    function __construct($name, Sledge $slegde)
    {
        parent::__construct($name);
        $this->sledge = $slegde;
    }

    function pull()
    {
        echo $this->sledge->pull();
    }
}

Dog is my regular entity and his only responsibility is to map database fields. Husky on the other hand has same responsibilities as dog but also delegates Sledge pulling.

Normally, both entities would have different repositories (should they? Since one inherits from one another) to call for, however business requirement implies that client does not have to specify dog's type (so it can either be a "basic" Dog or special Husky), just its name http://localhost/animal/fluffy.

What is more, currently they both reside in the same database table (recognized by type field) and right now there are no technical plans to change that (performance and time reasons).

What is the best way to do it?

  • Should I create some AnimalRepository, pull the data and treat it as DTO, detect it's type and then create appropriate class?
  • Should I create some kind of higher abstraction level mapper? How should it look like?
share|improve this question
add comment

2 Answers 2

I am not an expert on this subject, but will try an answer. According to this article the Repository pattern is specifically designed to solve your problem. So in my understanding you should have one repository that will return the concrete or abstract Animal required.

share|improve this answer
add comment

First off, you are violating Liskov Substitution Principle as Dog is not replaceable with Husky. Although the type system will allow it, if you pass a Non-Husky Dog in a method that calls sledge, then your system will have an unrecoverable error (non-existing methods in PHP are fatal errors).

Assuming you fix this modelling issue, then the repository will hold concrete derived instances of Dog in memory, which can be queried and manipulated.

Repository is fed externally with Dogs - either an external class which factorises Dogs into Repository; or even the Repository can have a method which accepts a driver to feed itself with Dogs.

The Factory which will render Dogs should be able to create the right from the information loaded from Database.

share|improve this answer
    
I don't know PHP but assuming all Husky does is add a new field and method, you can use Husky anywhere Dog is expected. There's no LSP violation there. –  Doval Jul 14 at 14:41
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.