possibile refactoring questi metodi che contengono lo stesso flusso logico?

1

Ho molti metodi in molti repository che hanno lo stesso flusso logico:

  1. Recupera valore dalla cache
  2. Controlla il valore
    1. Se nessun valore, recupera dal database
    2. Aggiorna cache
  3. Valore restituito

C'è un modo per refactoring questi metodi in modo tale che non devo riscrivere le stesse righe più e più volte?

Sto utilizzando un pattern MVC con servizi, ad es. Il servizio ActivityService ha Injected ActivityRepositoryInterface (molto probabilmente sarà la versione in cache concreta che vedi sotto). Posso incollare altro codice se aiuta?

Grazie

namespace DW\DWBundle\Repository\Cached;

use DW\DWBundle\Cache\ActivityCache;
use DW\DWBundle\Entity\User;
use DW\DWBundle\Helper\CacheHelper;
use DW\DWBundle\Repository\ActivityRepository as ActivityRepositoryInterface;
use DW\DWBundle\Repository\Doctrine\ORM\ActivityRepository as ActivityRepositoryDoctrine;

class ActivityRepository extends CustomRepository implements ActivityRepositoryInterface
{
    private $activityRepository;
    private $cacheHelper;

    public function __construct(ActivityRepositoryDoctrine $activityRepository, CacheHelper $cacheHelper)
    {
        parent::__construct($activityRepository);

        $this->activityRepository = $activityRepository;
        $this->cacheHelper = $cacheHelper;
    }

    public function findRecentLikeActivity($limit)
    {
        $key = ActivityCache::KEY_LIKES_WIDGET;
        $name = ActivityCache::CACHE_ACTIVITY;
        $classType = "ArrayCollection<DW\DWBundle\Entity\Activity>";
        $activity = $this->cacheHelper->getFromCache($key, $name, $classType);
        if ($activity == null) {
            $activity = $this->activityRepository->findRecentLikeActivity($limit);
            $this->cacheHelper->saveToCache($key, $name, $activity);
        }
        return $activity;
    }

    public function findRecentCommentActivity($limit)
    {
        $key = ActivityCache::KEY_COMMENTS_WIDGET;
        $name = ActivityCache::CACHE_ACTIVITY;
        $activity = $this->cacheHelper->getFromCache($key, $name, "ArrayCollection<DW\DWBundle\Entity\Activity>");
        if ($activity == null) {
            $activity = $this->activityRepository->findRecentCommentActivity($limit);
            $this->cacheHelper->saveToCache($key, $name, $activity);
        }
        return $activity;
    }

    public function findRecentActivity($limit)
    {
        $key = ActivityCache::KEY_ALL_WIDGET;
        $name = ActivityCache::CACHE_ACTIVITY;
        $activity = $this->cacheHelper->getFromCache($key, $name, "ArrayCollection<DW\DWBundle\Entity\Activity>");
        if ($activity == null) {
            $activity = $this->activityRepository->findRecentActivity($limit);
            $this->cacheHelper->saveToCache($key, $name, $activity);
        }
        return $activity;
    }

    public function findActivityByUser(User $user)
    {
        $key = ActivityCache::KEY_USER_ID."_".$user->getId();
        $name = ActivityCache::CACHE_ACTIVITY;
        $activity = $this->cacheHelper->getFromCache($key, $name, "ArrayCollection<DW\DWBundle\Entity\Activity>");
        if ($activity == null) {
            $activity = $this->activityRepository->findActivityByUser($user);
            $this->cacheHelper->saveToCache($key, $name, $activity);
        }
        return $activity;
    }

    public function findActivityOrderedByCreated()
    {
        $key = ActivityCache::KEY_LIST;
        $name = ActivityCache::CACHE_ACTIVITY;
        $activity = $this->cacheHelper->getFromCache($key, $name, "ArrayCollection<DW\DWBundle\Entity\Activity>");
        if ($activity == null) {
            $activity = $this->activityRepository->findActivityOrderedByCreated();
            $this->cacheHelper->saveToCache($key, $name, $activity);
        }
        return $activity;
    }

    public function findActivityOrderedByCreatedASC()
    {
        $key = ActivityCache::KEY_LIST_ASC;
        $name = ActivityCache::CACHE_ACTIVITY;
        $activity = $this->cacheHelper->getFromCache($key, $name, "ArrayCollection<DW\DWBundle\Entity\Activity>");
        if ($activity == null) {
            $activity = $this->activityRepository->findActivityOrderedByCreatedASC();
            $this->cacheHelper->saveToCache($key, $name, $activity);
        }
        return $activity;
    }
}

....

namespace DW\DWBundle\Helper;

use JMS\Serializer\Serializer;
use Tbbc\CacheBundle\Cache\CacheManagerInterface;
use Tbbc\CacheBundle\Cache\KeyGenerator\KeyGeneratorInterface;

class CacheHelper
{
    private $cacheManager;
    private $keyGenerator;
    private $serializer;

    public function __construct(CacheManagerInterface $cacheManager,
                                KeyGeneratorInterface $keyGenerator,
                                Serializer $serializer)
    {
        $this->cacheManager = $cacheManager;
        $this->keyGenerator = $keyGenerator;
        $this->serializer = $serializer;
    }

    public function getFromCache($key, $name, $classType)
    {
        $cacheKey = $this->keyGenerator->generateKey($key);
        $cache = $this->cacheManager->getCache($name);
        $serialized = $cache->get($cacheKey);
        $deserialized = $this->deserialize($serialized, $classType);
        return $deserialized;
    }

    public function saveToCache($key, $name, $value)
    {
        $cacheKey = $this->keyGenerator->generateKey($key);
        $cache = $this->cacheManager->getCache($name);
        $serialized = $this->serialize($value);
        $cache->set($cacheKey, $serialized);
    }

    public function deleteFromCache($key, $name)
    {
        $cacheKey = $this->keyGenerator->generateKey($key);
        $cache = $this->cacheManager->getCache($name);
        $cache->delete($cacheKey);
    }

    public function serialize($object)
    {
        return $this->serializer->serialize($object, 'json');
    }

    public function deserialize($data, $class)
    {
        return $this->serializer->deserialize($data, $class, 'json');
    }
}
    
posta Jonathan 05.01.2015 - 23:07
fonte

1 risposta

3

Potresti creare una terza classe che gestisce sia il repository che la cache. Quindi, non tentare manualmente di ottenere il valore memorizzato nella cache e, se non disponibile, eseguire una query sul repository come

$activity = $this->cacheHelper->getFromCache($key, $name, "ArrayCollection<DW\DWBundle\Entity\Activity>");
    if ($activity == null) {
        $activity = $this->activityRepository->findRecentCommentActivity($limit);
        $this->cacheHelper->saveToCache($key, $name, $activity);
    }

Piuttosto, il tuo CachedRepository risponderà:

$activity = $this->cachedRepository->getFromCacheOrRepository($key, $name, "ArrayCollection<DW\DWBundle\Entity\Activity>");

La logica di query cache e repository ora può essere implementata nella classe CachedRepository e quindi riutilizzata.

    
risposta data 05.01.2015 - 23:26
fonte

Leggi altre domande sui tag