Unit Corak Kerja
Gambaran Keseluruhan
Section titled “Gambaran Keseluruhan”Corak Unit Kerja mengekalkan senarai objek yang terjejas oleh transaksi perniagaan dan menyelaraskan menulis perubahan. Ia memastikan semua perubahan yang berkaitan dilakukan bersama-sama atau dibatalkan apabila kegagalan.
Tujuan
Section titled “Tujuan”- Pengurusan Transaksi - Operasi berkaitan kumpulan
- Tukar Penjejakan - Jejaki entiti yang diubah suai
- Operasi Kelompok - Optimumkan penulisan pangkalan data
- Ketekalan - Pastikan integriti data
Pelaksanaan
Section titled “Pelaksanaan”Unit Antara Muka Kerja
Section titled “Unit Antara Muka Kerja”<?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;}Pelaksanaan Asas
Section titled “Pelaksanaan Asas”<?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; }}Penggunaan dalam Perkhidmatan
Section titled “Penggunaan dalam Perkhidmatan”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; } }}Dengan Integrasi Repositori
Section titled “Dengan Integrasi Repositori”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); }}Amalan Terbaik
Section titled “Amalan Terbaik”- Transaksi Pendek - Pastikan transaksi ringkas
- Tanggungjawab Tunggal - Satu unit kerja bagi setiap operasi perniagaan
- Clear Boundaries - Tentukan skop transaksi dengan jelas
- Pengendalian Ralat - Sentiasa kendalikan senario rollback
- Elakkan Bersarang - Jangan sarangkan unit kerja
Dokumentasi Berkaitan
Section titled “Dokumentasi Berkaitan”- Lapisan Repositori - Corak repositori
- Lapisan Perkhidmatan - Corak perkhidmatan
- ../Database/Database-Schema - Operasi pangkalan data
- Model Domain - Entiti domain