رفتن به محتوا

واحد الگوی کار

الگوی واحد کار فهرستی از اشیاء تحت تأثیر یک معامله تجاری را حفظ می کند و نوشتن تغییرات را هماهنگ می کند. این تضمین می‌کند که همه تغییرات مرتبط با هم انجام می‌شوند یا در صورت عدم موفقیت، بازگردانده می‌شوند.

  1. مدیریت تراکنش - عملیات مرتبط با گروه
  2. تغییر ردیابی - ردیابی نهادهای اصلاح شده
  3. ** عملیات دسته ای ** - بهینه سازی پایگاه داده می نویسد
  4. **ثبات ** - اطمینان از یکپارچگی داده ها
<?php
declare(strict_types=1);
namespace XoopsModules\MyModule\Infrastructure;
interface UnitOfWorkInterface
{
public function begin(): void;
public function commit(): void;
public function rollback(): void;
public function registerNew(object $entity): void;
public function registerDirty(object $entity): void;
public function registerDeleted(object $entity): void;
}
<?php
declare(strict_types=1);
namespace XoopsModules\MyModule\Infrastructure;
final class UnitOfWork implements UnitOfWorkInterface
{
private array $newEntities = [];
private array $dirtyEntities = [];
private array $deletedEntities = [];
private bool $inTransaction = false;
public function __construct(
private readonly \XoopsDatabase $db,
private readonly EntityMapperRegistry $mappers
) {}
public function begin(): void
{
if ($this->inTransaction) {
throw new \RuntimeException('Transaction already started');
}
$this->db->query('START TRANSACTION');
$this->inTransaction = true;
}
public function commit(): void
{
if (!$this->inTransaction) {
throw new \RuntimeException('No transaction in progress');
}
try {
$this->insertNew();
$this->updateDirty();
$this->deleteRemoved();
$this->db->query('COMMIT');
$this->clear();
} catch (\Exception $e) {
$this->rollback();
throw $e;
}
}
public function rollback(): void
{
if ($this->inTransaction) {
$this->db->query('ROLLBACK');
$this->clear();
}
}
public function registerNew(object $entity): void
{
$id = spl_object_id($entity);
$this->newEntities[$id] = $entity;
}
public function registerDirty(object $entity): void
{
$id = spl_object_id($entity);
if (!isset($this->newEntities[$id])) {
$this->dirtyEntities[$id] = $entity;
}
}
public function registerDeleted(object $entity): void
{
$id = spl_object_id($entity);
unset($this->newEntities[$id], $this->dirtyEntities[$id]);
$this->deletedEntities[$id] = $entity;
}
private function insertNew(): void
{
foreach ($this->newEntities as $entity) {
$mapper = $this->mappers->getMapper($entity::class);
$mapper->insert($entity);
}
}
private function updateDirty(): void
{
foreach ($this->dirtyEntities as $entity) {
$mapper = $this->mappers->getMapper($entity::class);
$mapper->update($entity);
}
}
private function deleteRemoved(): void
{
foreach ($this->deletedEntities as $entity) {
$mapper = $this->mappers->getMapper($entity::class);
$mapper->delete($entity);
}
}
private function clear(): void
{
$this->newEntities = [];
$this->dirtyEntities = [];
$this->deletedEntities = [];
$this->inTransaction = false;
}
}
final class ArticleService
{
public function __construct(
private readonly UnitOfWorkInterface $unitOfWork,
private readonly ArticleRepository $articles,
private readonly CommentRepository $comments
) {}
public function publishWithComments(
Article $article,
array $comments
): void {
$this->unitOfWork->begin();
try {
// Mark article as modified
$article->publish();
$this->unitOfWork->registerDirty($article);
// Add new comments
foreach ($comments as $comment) {
$this->unitOfWork->registerNew($comment);
}
// Commit all changes together
$this->unitOfWork->commit();
} catch (\Exception $e) {
$this->unitOfWork->rollback();
throw $e;
}
}
}
final class ArticleRepository implements ArticleRepositoryInterface
{
public function __construct(
private readonly UnitOfWorkInterface $unitOfWork,
private readonly ArticleMapper $mapper
) {}
public function add(Article $article): void
{
$this->unitOfWork->registerNew($article);
}
public function update(Article $article): void
{
$this->unitOfWork->registerDirty($article);
}
public function remove(Article $article): void
{
$this->unitOfWork->registerDeleted($article);
}
public function findById(ArticleId $id): ?Article
{
return $this->mapper->findById($id);
}
}
  1. ** معاملات کوتاه ** - معاملات را مختصر نگه دارید
  2. ** مسئولیت واحد ** - یک واحد کار در هر عملیات تجاری
  3. مرزهای پاک - محدوده تراکنش را به وضوح تعریف کنید
  4. ** رسیدگی به خطا ** - همیشه سناریوهای بازگشت را مدیریت کنید
  5. اجتناب از Nested - واحدهای کار را تودرتو نکنید
  • Repository-Layer - Repository pattern
  • لایه سرویس - الگوی خدمات
  • ../Database/Database-Schema - عملیات پایگاه داده
  • Domain-Model - موجودیت های دامنه