First of all, I think you are mixing some things. It looks like your class is an InvoiceGenerator factory class . His responsibility is to create and return an invoice object. An Invoice object is not an InvoiceGenerator dependency (in this case, it would be better to pass an Invoice object as an argument, known as Injection Dependency ).
However, as I said, the InvoiceGenerator class is represented by the factory class, and the whole idea of the factory class is that the logic for creating an object instance is encapsulated inside this class (as in your second example). If you pass the Invoice object as an argument (as in the first example), you will need to create it somewhere else, and if there are several places in your code where this will happen, you will end up duplicating the logic of creating the instance. The whole idea of the factory pattern is to prevent this.
Using the factory class, you can encapsulate the object creation logic and avoid duplication. You can also add more complex logic to the InvoiceGenerator create() method to decide what type of object you want to return. For example, you might want to return an Invoice object if the total price is > 0 , but a CreditNote object if the price is < 0 . Of course, they must extend the same interface (e.g. InvoiceInterface ).
Also, it looks like you are delegating the actual initialization of the Invoice object to the object itself, since the create() method of InvoiceGenerator does nothing more than calling the create() method of the Invoice object, where the actual logic seems to be taking place. This violates the principle of the principle of single responsibility , since the Invoice class is now responsible for storing account setup data and data from the array. Instead, the latter should correspond to the factory class.
So, I would create a class as follows:
class InvoiceFactory { public function create(array $data) { if ($data['total'] >= 0) { $invoice = new Invoice(); } else { $invoice = new CreditNote(); } $invoice->setTotal($data['total']);
As you can see, there is no create() method that is called in the $invoice object.