4 Stimmen

PHP - ORM Lazy Load/Identity Map Implementierung Frage

Ich habe eine nackte Knochen ORM-Implementierung, bestehend aus Daten-Mapper, die laden und persist Entitäten. Jeder Mapper verwaltet intern eine Identitätszuordnung für alle Entitäten, die aus der Datenbank gelesen werden, so dass die gleiche Entität nur einmal in den Speicher geladen wird.

Ich implementiere derzeit Lazy Loading für verwandte Entitäten mit einer Proxy-Klasse, die die verwandten Daten nur lädt, wenn auf eine Eigenschaft der Entität zugegriffen wird. Mein Problem ist, dass die Proxy-Klasse nicht die Entität selbst ist und nur verwendet wird, wenn die Entität indirekt geladen wird (über eine Beziehung). Daher wird jede ===-Prüfung, die die tatsächliche Entität mit einem Proxy vergleicht, der die gleiche Entität lädt, false zurückgeben. Mein Ziel ist es, dass sowohl die Entitäten als auch der Client-Code nichts von den Proxy-Objekten wissen.

Die Proxy-Klasse sieht in etwa so aus:

class EntityProxy
{
    protected $_entity;
    protected $_loader;

    public function __construct(EntityProxyLoader $loader)
    {
        $this->_loader = $loader;
    }

    protected function _load()
    {
        if (null === $this->_entity)
        {
            $this->_entity = $this->_loader->load();
            unset($this->_loader);
        }
    }

    public function __get($name)
    {
        $this->_load();
        return $this->_entity->$name;
    }

    public function __set($name, $value)
    {
        $this->_load();
        $this->_entity->$name = $value;
    }
}

Und die Mapper sehen in etwa so aus:

class PersonEntityMapper
{
    // Find by primary key
    public function find($id)
    {
        if ($this->inIdentityMap($id)
        {
            return $this->loadFromIdentityMap($id);
        }

        $data = ...;  // gets the data

        $person = new Person($data);

        // Proxy placeholder for a related entity. Assume the loader is
        // supplied the information it needs in order to load the related 
        // entity.
        $person->Address = new EntityProxy(new EntityProxyLoader(...));

        $this->addToIdentityMap($id, $person);

        return $person;
    }
}

class AddressEntityMapper
{
    // Find by primary key
    public function find($id)
    {
        ...

        $address = new AddressEntity($data);

        $address->Person = new EntityProxy(new EntityProxyLoader(...));

        $this->addToIdentityMap($id, $address);

        return $address;
    }
}

Wenn ich einen "PersonEntity"-Datensatz lade, der eine verwandte "AddressEntity" hat, und dann denselben "AddressEntity"-Datensatz direkt über den "AddressEntityMapper" lade und die beiden Objekte vergleiche, sind sie nicht identisch (da eines ein Proxy ist, der delegiert). Gibt es eine Möglichkeit, den in PHP eingebauten Objektvergleich außer Kraft zu setzen? Gibt es Vorschläge für einen besseren Weg, dies zu handhaben, ohne proxybewussten Code in die Entitäten und/oder den Client-Code einzuführen?

Ich bin mir auch bewusst, dass es für mich von Vorteil wäre, ein bestehendes und etabliertes ORM zu übernehmen, aber es gibt verschiedene Probleme, die mich daran hindern, dies zu tun.

2voto

Chuck Vose Punkte 4453

Die übliche Methode ist die Erstellung einer Gleichheitsmethode, wie sie in Java üblich ist. PHP erlaubt es nicht, == oder === zu überschreiben, und ich habe noch nie eine Möglichkeit gefunden, Komparatoren zu überschreiben, aber ich habe mich schon einmal geirrt, und es wäre cool, wenn ich in diesem Fall falsch läge.

0voto

Keyne Viana Punkte 6094

Ich bin mir bei Ihrem Problem nicht sicher, aber ich denke, dass der Vergleich mit Hilfe von Schnittstellen und anstelle von == o === sollten Sie if($User instanceof UserInterface)

Sehen Sie: http://www.davegardner.me.uk/blog/tag/lazy-load/

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X