What does a domain factory object look like?

I have DataMapperFactory

, and I think I'm doing it right and it makes sense to have it, but I have DomainObjectFactory

, but it just seems pointless. It's him:

namespace libs\factories;
use models as Models;

class DomainObjectFactory {

    public function build($name) {

        $className = 'Models\\' . $name;

        return new className();

    }

}

      

The only benefit I see with this is that I keep the operator new

from being present in all of my code.

There must be more than that right?

Any help would be greatly appreciated.

+3


source to share


3 answers


In general, you can use a factory for abstract from certain implementations. If you use an operator new <classname>

, you create a specific class each time. If you want to change this class to a different implementation later, you will have to manually change each statement new

.

The factory pattern allows you to abstract from certain classes. A valid minimum use case might be something like this:



interface UserInterface {
    public function getName();
}

class UserImplementationA implements UserInterface {
    private $name;
    public function getName() { return $this->name; }
}

class UserImplementationB implements UserInterface {
    public function getName() { return "Fritz"; }
}

class UserFactory {
    public function createUser() {
        if (/* some condition */) return new UserImplementationA();
        else                      return new UserImplementationB();
    }
}

$f = new UserFactory();
$u = $f->createUser();   // At this point, you don't really have to care 
                         // whether $u is an UserImplementationA or
                         // UserImplementationB, you can just treat it as
                         // an instance of UserInterface.

      

One use case (out of many) where this becomes extremely useful is when working with unit tests. In Test-Driven Development, you often replace class dependencies with mock objects (objects that implement a specific interface, but don't actually do anything). Using a factory pattern, it is fairly easy to transparently replace certain classes with mock classes.

+5


source


There are main reasons for using factories:

1. Abstract creation of an object

This is one of the most useful frameworks in your architecture when it comes to unit testing. Having a factory in charge of instantiation makes it easier to introduce mocks when testing.

Also, as an added benefit, you are no longer tied to the name of the classes you use.

2. Simplify the instance

Here, you have two aspects to consider. Firstly - the ability to instantiate different objects based on some state - has already been described quite well in helmbert's answer (+ 1 for him) sub>.

Another case is when you create domain objects that are more complex. Something like that:

$employees = new EmployeeCollection;
$address = new Location;
$class = $type . `Company`;
$company = new $class( $employee, $address );

      



There is a HoldingCompany

lot to do before instantiation . But this whole process can be done with a factory. Especially if your domain factory object makes good use of a properly implemented DIC (which is quite rare, by the way).

3. Prepare objects before releasing them in the application

You should never do any calculations in the constructor. This makes it impossible to validate this code. Constructors should only contain simple variable assignments.

But this introduces a problem: sometimes you need to do a few logical operations before you can let other code structures handle your object instance. As newbies, we usually do this in a constructor. But where to put it now?

This is where factories come to the rescue.

public function create( $name )
{
     $instance = new $name;
     if ( is_callable($instance, false, 'prepare') )
     {
         $instance->prepare();
     }
     return $instance;
}

      

Now that you use $factory->create('foobar')

, your object will be completely primed for use.


+6


source


public function build($name) {

        $className = 'Models\\' . $name;

        return new $className();
}

      

This will work for you.

Defining object objects is good practice when you want to set some default properties for objects, and you also don't have to worry about what namespace or directory exists in a particular class.

Example:

public function createButton($name){
    require("home/lib/display/Button.php") ;

    $button = new Button($name, "some default param") ;
    $button->visible = true ;
    return $button ;
}

      

You just make default objects so quickly through factories like this, besides saving the word new

.

+1


source







All Articles