0

Im working on a project where we're creating many objects throughout the code base.

For some objects thus we decided to use factories to control the process of creating the objects and all their dependencies. This is an example of what we are trying to do:

class CreateBranchFactory implements CreateBranchInterface {

    private $branch;

    public function __construct() {
        $this->branch = new Branch();
        $this->branch->scenario = 'create';
    }

    public function createBranch($branchForm) {
        $this->branch->attributes = $branchForm->attributes;

        //Example of all the things that I need to do after creating my object
        $this->setOfficialNameAndPrinterName($branchForm->official_name, $branchForm->printer_name, $branchForm->name);
        $this->createDependencies1();
        $this->someOtherFunction();

        return $this->branch;
    }

    public function setOfficialNameAndPrinterName($offName, $printerName, $branchName) {
        $this->branch->official_name = $offName ?? $branchName;
        $this->branch->printer_name = $printerName ?? $branchName;
        $this->branch->save();
    }

    public function createDependencies1() {

    }

And to have a proper contract I created an interface for this. This interface specifies the functions that should be defined

interface CreateBranchInterface {

    public function setOfficialNameAndPrinterName(String $offName, String $printerName, String $branchName);

    public function createDependencies1();
}

My problem though, is that the contract is specifying all the functions that should be defined, but isnt controlling which functions should get called. Is there any design pattern that I can use, that makes sure that those functions get called??

mrateb
  • 2,317
  • 5
  • 27
  • 56
  • Why would you want to ensure that all functions are being *called*?! You should rather move every work that *must* get done into one function, and tie the success of the operation to that function being called. E.g., that function should be the constructor, or the function that will also deliver the requested result. – deceze Jul 26 '18 at 15:49
  • Because Im doing many things, I want to have a separte "description" for the things Im doing. Example: When creatingTheBranch, I 1.CreatePostalAddress() 2.CreateShippingAddress() 3.CreateAPhoneLine(),... – mrateb Jul 26 '18 at 15:51
  • This is just an example, but the point is, I want a place where I can see all the things that I need to do when Im creating my object – mrateb Jul 26 '18 at 15:51
  • Well then create one encapsulating function somewhere which does all these steps in one go. You *want* to be able to call each function individually, because obviously you want to be able to create a branch and a printer independently (for example). But if the procedure for doing X requires that both are done together, then create a new `function doX` which calls both those methods. – deceze Jul 26 '18 at 15:55

1 Answers1

2

You can't create such contract by using interfaces - interfaces specifies which methods and how you can call. Calling all these methods is part of implementation, which cannot be provided by interface. You need to create abstract class with implementation and use final keyword to disallow overriding it:

abstract class CreateBranch {

    abstract protected function getBranch(): Branch;

    final public function createBranch($branchForm) {
        $this->getBranch()->attributes = $branchForm->attributes;

        //Example of all the things that I need to do after creating my object
        $this->setOfficialNameAndPrinterName($branchForm->official_name, $branchForm->printer_name, $branchForm->name);
        $this->createDependencies1();
        $this->someOtherFunction();

        return $this->getBranch();
    }

    abstract public function setOfficialNameAndPrinterName(String $offName, String $printerName, String $branchName);

    abstract public function createDependencies1();

    abstract public function someOtherFunction();
}
rob006
  • 21,383
  • 5
  • 53
  • 74