izzum\statemachine\EntityBuilder::getEntity PHP Method

getEntity() final public method

Gets an application domain specific model of choice, as implemented by a subclass.
See also: Context::getEntity()
final public getEntity ( Identifier $identifier, boolean $create_fresh_entity = false ) : Object
$identifier Identifier
$create_fresh_entity boolean optional. if true, then a new instance is always created, else it might be cached if used for the same Identifier (performance). Since a statemachine might run multiple transitions in memory and alter the data in the persistence layer, there might be a need to refresh the entity (create it again) if the in memory object and the data in the persistence layer are not synchronized. this might cause rules or commands to act on in-memory data while it should use the persisted data. (an ORM should handle this automatically)
return Object an object of any type, depending on the statemachine. This object will be used by the Rule and Command that go with a certain statemachine. It will be injected in the constructor of the Rule and Command. It implements caching so we always get the same entity instance on each call of 'getEntity' with the same Context
    public final function getEntity(Identifier $identifier, $create_fresh_entity = false)
    {
        try {
            // lazy loading with caching.
            // we cache the context so we can be sure to provide
            // a new reference to the entity when the builder is used on a new
            // Identifier.
            if ($this->entity === null || $this->identifier !== $identifier || $create_fresh_entity === true) {
                // crate new entity and build cache
                $this->entity = $this->build($identifier);
                $this->identifier = $identifier;
            }
            return $this->entity;
        } catch (Exception $e) {
            // already a statemachine exception, just rethrow, it is logged
            throw $e;
        } catch (\Exception $e) {
            // a non statemachine type exception, wrap it so it is logged and
            // throw
            $e = new Exception($e->getMessage(), Exception::BUILDER_FAILURE, $e);
            throw $e;
        }
    }

Usage Example

 public function testDefaultBuilder()
 {
     //create Entity in default state. this is enough to pass it
     //to the builder
     $object_1 = new Identifier(-1, 'order');
     $object_2 = new Identifier(-2, 'order');
     $this->assertNotEquals($object_1, $object_2);
     //scenario: call it twice with same object
     $builder = new EntityBuilder();
     $result_1 = $builder->getEntity($object_1);
     $this->assertEquals($object_1, $result_1);
     //same result when we call it again (should be cached, but we can only test
     //this when we override the protected build() method of the builder).
     $result_2 = $builder->getEntity($object_1);
     $this->assertEquals($object_1, $result_2);
     $this->assertEquals($result_1, $result_2, 'obviously');
     $this->assertEquals('izzum\\statemachine\\EntityBuilder', $builder->toString());
     //scenario: call it with different objects
     $builder = new EntityBuilder();
     $result_1 = $builder->getEntity($object_1);
     $this->assertEquals($object_1, $result_1);
     //different result when we call it again
     $result_2 = $builder->getEntity($object_2);
     $this->assertEquals($object_2, $result_2);
     $this->assertContains('EntityBuilder', $builder . '', '__toString()');
 }