نمط وحدة العمل
نظرة عامة
Section titled “نظرة عامة”نمط وحدة العمل يحتفظ بقائمة الكائنات المتأثرة بمعاملة عمل وينسق كتابة التغييرات. يضمن التزام جميع التغييرات ذات الصلة معاً أو التراجع عند الفشل.
- إدارة المعاملات - تجميع العمليات ذات الصلة
- تتبع التغييرات - تتبع الكيانات المعدلة
- العمليات الدفعية - تحسين كتابات قاعدة البيانات
- الاتساق - ضمان تكامل البيانات
التنفيذ
Section titled “التنفيذ”واجهة وحدة العمل
Section titled “واجهة وحدة العمل”<?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;}التنفيذ الأساسي
Section titled “التنفيذ الأساسي”<?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; }}الاستخدام في الخدمات
Section titled “الاستخدام في الخدمات”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 { // علم المقالة كمعدلة $article->publish(); $this->unitOfWork->registerDirty($article);
// إضافة تعليقات جديدة foreach ($comments as $comment) { $this->unitOfWork->registerNew($comment); }
// التزم بجميع التغييرات معاً $this->unitOfWork->commit();
} catch (\Exception $e) { $this->unitOfWork->rollback(); throw $e; } }}مع تكامل المستودع
Section titled “مع تكامل المستودع”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); }}أفضل الممارسات
Section titled “أفضل الممارسات”- معاملات قصيرة - احتفظ بالمعاملات مختصرة
- مسؤولية واحدة - وحدة عمل واحدة لكل عملية عمل
- حدود واضحة - حدد نطاق المعاملة بوضوح
- معالجة الأخطاء - تعامل دائماً مع سيناريوهات التراجع
- تجنب التداخل - لا تتداخل وحدات العمل
الوثائق ذات الصلة
Section titled “الوثائق ذات الصلة”- Repository-Layer - نمط المستودع
- Service-Layer - نمط الخدمة
- ../Database/Database-Schema - عمليات قاعدة البيانات
- Domain-Model - كيانات المجال