J'ai aussi roulé mon propre ORM beaucoup de fois que je déteste dire! La mise en cache/mémorisation est assez facile si toutes vos récupérations se font par le biais d'une seule API (ou de ses sous-classes).
Pour toute récupération basée sur une clé unique, vous pouvez simplement mettre en cache en fonction d'une concaténation des clés. Une approche naïve pourrait être:
my %_cache;
sub get_object_from_db {
my ($self, $table, %table_lookup_key) = @_;
# concatenate a unique key for this object
my $cache_key = join('|', map { "$_|$table_lookup_key{$_}" }
sort keys %table_lookup_key
return $_cache{$cache_key}
if exists $_cache{$cache_key};
# otherwise get the object from the db and cache it in the hash
# before returning
}
Au lieu d'un hachage, vous pouvez utiliser le cache :: suite de modules sur CPAN pour respecter des délais et de la mémoire dans le cache.
Si vous souhaitez mettre en cache pendant un certain temps, vous pouvez envisager d'expirer des objets dans le cache. Si, par exemple, toutes vos mises à jour passent également par l'ORM, vous pouvez effacer (ou mettre à jour) l'entrée de cache dans votre méthode ORM update(). Un dernier point à considérer avec attention - vous renvoyez le même objet à chaque fois, ce qui a des implications. Si, par exemple, un morceau de code récupère un objet et met à jour une valeur mais ne valide pas cette modification sur la base de données, tous les autres codes récupérant cet objet verront cette modification. Cela peut être très utile si vous enchaînez une série d'opérations - ils peuvent tous mettre à jour l'objet et ensuite vous pouvez le valider à la fin - mais ce n'est peut-être pas ce que vous voulez. Je place habituellement un drapeau sur l'objet quand il est frais de la base de données et puis dans votre méthode de setter invalide cet indicateur si l'objet est mis à jour - de cette façon vous pouvez toujours vérifier ce drapeau si vous voulez vraiment un nouvel objet.