Skip to content

Instantly share code, notes, and snippets.

@dpobel
Created June 21, 2011 12:33
Show Gist options
  • Select an option

  • Save dpobel/1037758 to your computer and use it in GitHub Desktop.

Select an option

Save dpobel/1037758 to your computer and use it in GitHub Desktop.
Avoid repository call in objects (ie lazy load)
<?php
namespace ezp\Content;
class Location extends Base implements \ezp\DomainObjectInterface
{
// lots of stuff before
/**
* Parent Location of the Location or a Proxy object representing it
*
* @var Proxy|Location
*/
protected $parent;
// replace $parentId public property ?
// and if we need to get only the parentId, we can add a dynamicProperty
/**
* Sets the parent
*
* @param Proxy|Location $parentLocation
* @return void
*/
protected function setParent( $parentLocation )
{
$this->parent = $parentLocation;
}
protected function getParent()
{
if ( $this->parent instanceof Proxy )
{
$this->parent = $this->parent->load();
}
return $this->parent;
}
// lots of stuff after
}
<?php
namespace ezp\Base;
class Proxy
{
/**
* A service object
*
* @var Service
*/
protected $service;
/**
* ID of the object
*
* @var mixed
*/
protected $id;
/**
* Method to use on the service to load the object
*
* @var string
*/
protected $method;
/**
* __construct
*
* @param Services $service
* @param mixed $id
* @param string $method
*/
public function __construct( Services $service, $id, $method = 'load' )
{
$this->service = $service;
$this->id = $id;
$this->method = $method;
}
public function load()
{
return call_user_func( array( $this->service, $this->method ), $this->id );
}
}
?>
@andrerom

Copy link
Copy Markdown

To avoid proxy classes we could maybe use reference objects (not same reference object concept as in consolidated API doc)
This is a class that Storage Engine needs to implement:
interface Reference
{
public function getObject();
}

So Location would look like this:

namespace ezp\Content;
class Location extends ContentModel
{
// lots of stuff before
protected function getParent()
{
if ( $this->parent instanceof Reference )
return $this->parent = $this->parent->getObject();
return $this->parent;
}

// lots of stuff after

}

@dpobel

dpobel commented Jun 22, 2011

Copy link
Copy Markdown
Author

That sounds a good idea if we really need to avoid repository/service calls in domain objects.

that's close to Reference in the consolidated API doc except that in the doc, reference seems to be defined only for Content while the example here is about Location and we'll probably need the same mechanism for others objects (Section, User?, ...)

@andrerom

Copy link
Copy Markdown

As discussed it is a proxy object, and like collections it is generic, something like this perhaps:

interface Proxy
{
    public function __construct( Handler $handler, int $id, string $function = 'load' );

    /**
     * Load the object this proxy object represent
     *
     * @return DomainObject
     */
    public function load();
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment