patternphpMinor
Repository Pattern without an ORM
Viewed 0 times
patternormwithoutrepository
Problem
I'm trying to learn the Repository pattern, and I have some questions regarding my current understanding of it.
Here is my current implementation, as far as I understand the concepts.
Product.php
ProductRepositoryInterface.php
ProductRepository.php
```
db = $db;
}
/**
* @return array
*/
public function findAll()
{
$stmt = $this->db->query(
'SELECT
id
- All the examples I've been able to find of database repositories use ORMs, but for a number of reasons, I can't use an ORM in the project I am learning this for. So, when not using an ORM, where should the SQL queries go? My best guess was in the repository class itself, so that's what I did in the example below.
- How's my naming convention for the repository's methods? I stuck with the create/update/delete verbiage of SQL as a sort of placeholder, but is there a better way?
- Because I'm not using an ORM, I need a
setId()method in my repository. I recognize the danger inherent in allowing id's to be changed after object creation. Right now I prevent that by throwing an exception insetId()if id is not null. Is that alright or is there a better way?
- Am I doing anything just completely wrong in general?
Here is my current implementation, as far as I understand the concepts.
Product.php
id;
}
public function setId($id)
{
if ($this->id !== null) {
throw new Exception('id cannot be reset.');
}
$this->id = $id;
return $this;
}
public function getName()
{
return $this->name;
}
public function setName($name)
{
$this->name = $name;
return $this;
}
}ProductRepositoryInterface.php
<?php
namespace Vendor\Package\Module\Repositories;
use PDO;
use Vendor\Package\Module\Entities\Product;
interface ProductRepositoryInterface
{
public function findAll();
public function findById($id);
public function create(Product $product);
public function update(Product $product);
public function delete(Product $product);
}ProductRepository.php
```
db = $db;
}
/**
* @return array
*/
public function findAll()
{
$stmt = $this->db->query(
'SELECT
id
Solution
A quick answer regarding the
You should use the object's constructor instead like this:
So if the entity is created for the fist time you have to call
With this trick you can make a single
For the id question, two options:
In this second case (you handle the generation of the ID), your class will look like this:
Hope it can help !
setId method.You should use the object's constructor instead like this:
class Product
{
/** @var int $id */
protected $id;
/** @var string $name */
protected $name;
public function __construct($id = null)
{
$this->id = $id;
}
public function isNew()
{
return is_null($this->id)
}
}So if the entity is created for the fist time you have to call
$product = new Product() and if you fetch it from the database: $product = new Product($result['id']);.With this trick you can make a single
save operation for your repository: class ProductRepository implements ProductRepositoryInterface
{
public function save(Product $product)
{
if($product->isNew())
$this->create($product);
else
$this->update($product);
}
}For the id question, two options:
- When you insert a new object, you'll make a new one with the id from the database
- You'll handle the generation of the Id by yourself using an UUID for example (this lib is perfect for that: https://github.com/ramsey/uuid)
In this second case (you handle the generation of the ID), your class will look like this:
class Product
{
/** @var int $id */
protected $id;
/** @var string $name */
protected $name;
protected $isNew = false;
public function __construct($id = null)
{
if($id === null) {
$this->id = Uuid::uuid4();
$this->isNew = true;
} else {
$this->id = $id;
}
}
}Hope it can help !
Code Snippets
class Product
{
/** @var int $id */
protected $id;
/** @var string $name */
protected $name;
public function __construct($id = null)
{
$this->id = $id;
}
public function isNew()
{
return is_null($this->id)
}
}class ProductRepository implements ProductRepositoryInterface
{
public function save(Product $product)
{
if($product->isNew())
$this->create($product);
else
$this->update($product);
}
}class Product
{
/** @var int $id */
protected $id;
/** @var string $name */
protected $name;
protected $isNew = false;
public function __construct($id = null)
{
if($id === null) {
$this->id = Uuid::uuid4();
$this->isNew = true;
} else {
$this->id = $id;
}
}
}Context
StackExchange Code Review Q#126050, answer score: 2
Revisions (0)
No revisions yet.