3

I have a base class called ProductRepository and there are other classes which extends it; such as PushProductRepository or SocialProductRepository.

class ProductRepository implements ProductRepositoryInterface
{
    private $product;

    public function __construct(Product $product)
    {
        $this->product = $product;
    }

    public function create($name, $language, $type)
    {
        $this->product->create([
            'name' => $name,
            'language' => $language,
            'type' => $type
        ]);
    }
}

As you can see there is a type parameter in create function. It may be the values such as 'push' or 'social'. It will take the value from the classes which extends it. Instead of sending it as a parameter; I want to have a different approach. I will create a property in ProductRepository such as type and use $this->type in create function.

But I want to be sure that every class that extends ProductRepository should set this property in it's own class (probably in it's constructor)

How can I be sure that every class that extends ProductRepository will set type in it's constructor ? Is there any better way to achieve this? Is this violates anything? If it is so, how can i prevent it ?

3

Without delving into whether it's good or bad approach and just answering the question how?, I would make ProductRepository abstract, with abstract getType() method. So it would look like the following:

abstract class ProductRepository
{
    private $product;

    public function __construct(Product $product)
    {
        $this->product = $product;
    }

    public function create($name, $language, $type)
    {
        $this->product->create([
            'name' => $name,
            'language' => $language,
            'type' => $this->getType()
        ]);
    }

    abstract protected function getType();
}

As far as I can tell, type has something to do with a product itself, that is, with domain, so I would discourage building this logic in repository. What about creating a product with specific type property? It looks way cleaner for me -- at least domain logic resides in domain. And I don't understand why create method belongs to product. Probably you should have ProductRepository looking like that:

class ProductRepository
{
    private $dataStorage;

    public function __construct(DataStorage $dataStorage)
    {
        $this->dataStorage = $dataStorage;
    }

    public function add(Product $product)
    {
        $this->dataStorage
            ->insert(
                $product->getName(),
                $product->getLanguage(),
                $product->getType()
            )
        ;
    }
}
  • Product is a model (orm) and in that case create method is it's own method. What should i do when i need to instantiate ProductRepository ? – Bold P. Dec 27 '17 at 20:09
  • Um, what ORM are you using? I just can't realize why on Earth you need to call create method on an entity, and moreover, pass the entities properties as arguments. Why, if you already have them within that entity? – Zapadlo Dec 28 '17 at 7:19
  • > What should i do when i need to instantiate ProductRepository ? Typically you need some DAL (like Doctrine's), or just PDO. – Zapadlo Dec 28 '17 at 7:22
  • It is eloquent (laravel) and model is injected and it doesn’t have a knowledge about it’s properties, so i don’t have them in my model. When i said about instantiating i mean I can’t instantiate an abstract class if i turn it into concrete one then I can’t use abstract method ? – Bold P. Dec 31 '17 at 7:47

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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