1

I tried to create a rather complex domain called Vacancy, here is the details:

Vacancy.php

class Vacancy extends AbstractEntity implements AggregateRootInterface {
    private $employer;
    private $title;
    private $employerInformation;
    private $position;
    private $category;
    private $employmentInformation;
    private $hideSalary = false;
    private $requiredPerson = 1;
    private $yearsExp = 0;
    private $location;
    private $benefits;
    private $qualification;
    private $details;
    private $postedOn;
    private $lastPostPackage;
    private $expiredOn;
    private $visible = true;

    public function __construct(
        PackageOnHand $package,
        $title,
        Position $position,
        JobCategory $category,
        $employerInformation,
        EmploymentInformation $employmentInformation,
        City $location,
        $qualification
    ) {
        parent::__construct();

        $this->employer = $package->getEmployer();
        $this->title = $title;
        $this->position = $position;
        $this->category = $category;
        $this->employerInformation = $employerInformation;
        $this->employmentInformation = $employmentInformation;
        $this->location = $location;
        $this->setQualification($qualification);
        $this->benefits = new ArrayCollection();
        $this->details = new ArrayCollection();
    }

    // Bunch of setters, getters and methods I don't even want to mention
}

The EmploymentInformation class is already encapsulates 4 required parameters, which makes it an entity (and I personally feels wrong about it).

As can be seen, this particular domain model's constructor is extended to 8 parameters, not to mention the possibility to add some more.

The problem is, all of those parameters does required to make a single Vacancy into it's valid state.

I've read about Builder Pattern in this SO question, but it suggested that the Builder class is made into a nested class inside, which can't be done in PHP.

Is there any other pattern I can use to clear up constructor bloat?

Community
  • 1
  • 1
Samuel Adam
  • 1,327
  • 4
  • 26
  • 45
  • 2
    Rather than doing a nested class inside of your class you have in the above code, could you do just a completely separate class made up of the parameters needed for your classes constructor, and pass in instance of newly created, separate class class into the vacancy class? – Kritner Jul 03 '14 at 11:57
  • @Kritner Can you give me an example? – Samuel Adam Jul 03 '14 at 12:33
  • 1
    Well from the link from your original question it shows the nested class, you could pull that out into it's own class rather than nesting it within a class. Now that I think about however it I don't think it would fix your issue, it would only redirect the constructor bloat to a different class. If all of your parameters are still required, you would likely still want to set them up through the constructor I would think. – Kritner Jul 03 '14 at 14:51
  • I'm thinking that he could just pass in an array, and have the constructor immediately call a private `setFromArray` method that sets all the properties. Then the constructor then calls an `isValid` method to ensure the required properties are set. This way his properties stay private, he only needs to pass 1 argument (an array, that may be valid/invalid) and the constructor will throw an exception/error if not valid (ensuring the entity isn't instantiated in an invalid state). – prograhammer Apr 28 '15 at 21:18

1 Answers1

0

There might be several issues with your class.

Firstly, most likely you are violating SRP (single responsibility principle). Watch this: http://vimeo.com/43592685

Second. In constructor you pass things that are needed for all methods to work. Since you didn't specify any methods (getters and setters are not a methods I'm talking about) I can't tell if you need all of these parameters. In DDD your methods should mirror UL (ubiquitos language). For now it looks just like a container for data (anemic entity).

Builder pattern can be implemented in a various ways, you don't need nested classes. But builders are used for a different purpose, you should't use it here. I would simply make a factory for that.

I would also think about using "a specification" pattern here.

Rafał Łużyński
  • 7,083
  • 5
  • 26
  • 38