[Design Patterns]: Repository

Provides a more object-oriented view of the persistence layer. It encapsulates the set of objects persisted in a data store and the operations performed over them. Supports the objective of clean separation between the domain and data mapping layers.

Example:

class Order
{
   /**
    * @var int
    */
   private $id;
   /**
    * @var string
    */
   private $name;
   /**
    * @var DateTime
    */
   private $date;

   public function __construct(int $id, string $name, DateTime $date)
   {
      $this->id = $id;
      $this->name = $name;
      $this->date = $date;
   }

   public static function fromState(array $state): Order
   {
      return new self($state['id'], $state['name'], $state['date']);
   }

   /**
    * @return int
    */
   public function getId(): int
   {
      return $this->id;
   }

   /**
    * @return string
    */
   public function getName(): string
   {
      return $this->name;
   }

   /**
    * @return DateTime
    */
   public function getDate(): DateTime
   {
      return $this->date;
   }
}


interface Persistence
{
   public function generateId();

   public function persist(array $data);

   public function retrieve(int $id);

   public function delete(int $id);
}

class MemoryPersistence implements Persistence
{

   private $data = [];
   public $lastId = 0;


   public function generateId()
   {
      $this->lastId++;
      return $this->lastId;
   }

   public function persist(array $data)
   {
      $this->data[$this->lastId] = $data;
   }

   public function retrieve(int $id)
   {
      if (!isset($data[$id])) {
         throw new OutOfBoundsException('Cannot find the requested record!');
      }
      return $this->data[$id];
   }

   public function delete(int $id)
   {
      if (!isset($data[$id])) {
         throw new OutOfBoundsException('Cannot find the requested record!');
      }
      unset($this->data[$id]);
   }

}

class OrderRepository
{
   /**
    * @var Persistence
    */
   private $persistence;


   /**
    * OrderRepository constructor.
    */
   public function __construct(Persistence $persistence)
   {
      $this->persistence = $persistence;
   }

   public function generateId(): integer
   {
      return $this->persistence->generateId();
   }

   public function findById(integer $id)
   {
      $arrayData = $this->persistence->retrieve($id);
      return Order::fromState($arrayData);
   }

   public function save(Order $order)
   {
      $this->persistence->persist([
         'id' => $order->getId(),
         'name' => $order->getName(),
         'date' => $order->getDate(),
      ]);
   }
}

$orderRepository = new OrderRepository(new MemoryPersistence());

$order = Order::fromState([
   'id'=>12,
   'name'=>'Flowers Order',
   'date'=>new DateTime()
]);

$orderRepository->save($order);
$orderInPersistence = $orderRepository->findById(12);

print_r($order);
print_r($orderInPersistence);

Majd Arbash

Leave a Reply