در پروژههای PHP معمولاً برای کار با اطلاعات دیتابیس از مدلها، Repositoryها، Serviceها یا Query Builder استفاده میکنیم.
برای مثال، در یک فروشگاه اینترنتی ممکن است جدولی به نام orders داشته باشیم که سفارشهای کاربران در آن ذخیره میشوند.
در یک طراحی ساده، برای هر سفارش یک Object جداگانه میسازیم:
$order = new Order();
اما همیشه لازم نیست منطق برنامه را بر اساس Objectهای مستقل هر رکورد طراحی کنیم.
گاهی بهتر است منطق مربوط به تمام ردیفهای یک جدول در یک کلاس واحد قرار بگیرد.
این دقیقاً همان ایده اصلی Table Module Pattern است.
در این مقاله یاد میگیریم:
- Table Module Pattern چیست.
- چه تفاوتی با Domain Model دارد.
- چگونه آن را با PHP پیادهسازی کنیم.
- چه ارتباطی با Table Data Gateway دارد.
- در Laravel چگونه از آن استفاده کنیم.
- چه زمانی این الگو مناسب و چه زمانی نامناسب است.
Table Module Pattern چیست؟
Table Module یکی از الگوهای مربوط به سازماندهی Domain Logic در معماری نرمافزارهای سازمانی است.
Martin Fowler این الگو را چنین تعریف میکند:
> یک نمونه از کلاس که منطق کسبوکار مربوط به تمام ردیفهای یک جدول یا View را مدیریت میکند.
در این الگو معمولاً برای هر جدول دیتابیس یک کلاس در نظر گرفته میشود.
برای مثال:
users → UserTableModule
orders → OrderTableModule
products → ProductTableModule
invoices → InvoiceTableModule
در این ساختار، یک نمونه از OrderTableModule میتواند عملیات مربوط به تمام سفارشها را انجام دهد.
$orderModule = new OrderTableModule();
$orderModule->findById(10);
$orderModule->create($data);
$orderModule->cancel(10);
$orderModule->getPendingOrders();
نکته مهم این است که در Table Module برای هر ردیف جدول الزاماً یک Object مستقل ساخته نمیشود. در عوض، یک Object مسئول مدیریت منطق مربوط به کل جدول است. <Cite refs={["turn0search1","turn0search4"]} />
Table Module چه مشکلی را حل میکند؟
فرض کنید جدول سفارشها چنین دادههایی دارد:
orders
------------------------------------------------
id | user_id | status | total
------------------------------------------------
1 | 10 | pending | 2500000
2 | 11 | paid | 1800000
3 | 12 | cancelled | 900000
حالا چند عملیات مختلف روی این جدول داریم:
- دریافت سفارش بر اساس شناسه
- ایجاد سفارش
- محاسبه مبلغ سفارشها
- دریافت سفارشهای پرداختنشده
- لغو سفارش
- محاسبه فروش روزانه
- دریافت سفارشهای یک کاربر
- بررسی وضعیت سفارشها
اگر این منطق را در چندین Controller یا فایل پراکنده قرار دهیم، نگهداری آن سختتر میشود.
در Table Module همه این عملیات در یک کلاس مربوط به جدول سفارشها قرار میگیرند:
OrderTableModule
├── create()
├── findById()
├── cancel()
├── getPendingOrders()
├── calculateDailySales()
└── getUserOrders()
این ساختار برای سیستمهایی مناسب است که منطق آنها بیشتر حول جدولها و عملیات روی مجموعهای از رکوردها شکل گرفته است.
ساختار کلی Table Module
ساختار ساده این الگو را میتوان به صورت زیر نمایش داد:
Controller
|
v
OrderTableModule
|
+── create()
+── findById()
+── update()
+── cancel()
+── getPendingOrders()
|
v
Table Data Gateway
|
v
Database
در این ساختار:
- Controller درخواست کاربر را دریافت میکند.
- Table Module منطق کسبوکار را اجرا میکند.
- Table Data Gateway ارتباط با جدول دیتابیس را مدیریت میکند.
- Database دادهها را ذخیره میکند.
Table Module و Table Data Gateway دو مفهوم متفاوت هستند.
Table Module مسئول Business Logic است، اما Table Data Gateway بیشتر مسئول دسترسی به جدول دیتابیس است.
# تفاوت Table Module و Domain Model
در Domain Model معمولاً برای هر Entity یک Object مستقل داریم.
برای مثال:
$order = new Order(
id: 10,
total: 2500000
);
اگر ۱۰۰ سفارش داشته باشیم، میتوانیم ۱۰۰ نمونه از Order داشته باشیم.
اما در Table Module ممکن است فقط یک نمونه از کلاس مدیریت سفارشها داشته باشیم:
$orderModule = new OrderTableModule();
و همین Object روی همه سفارشها کار کند.
Martin Fowler تفاوت اصلی این دو الگو را در همین موضوع میداند: در Domain Model برای هر سفارش یک Object وجود دارد، اما در Table Module یک Object منطق تمام سفارشهای جدول را مدیریت میکند. <Cite refs={["turn0search1","turn0search4"]} />
Domain Model
Order #1 → Order Object
Order #2 → Order Object
Order #3 → Order Object
Table Module
All Orders → One OrderTableModule
هیچکدام به صورت مطلق برای همه پروژهها مناسب نیستند.
انتخاب بین آنها به پیچیدگی Business Logic و نوع دادههای برنامه بستگی دارد.
# تفاوت Table Module و Transaction Script
در Transaction Script معمولاً هر عملیات به صورت یک Procedure یا متد مستقل سازماندهی میشود.
برای مثال:
createOrder()
payOrder()
cancelOrder()
اما در Table Module، این عملیات در یک کلاس مرتبط با جدول قرار میگیرند:
OrderTableModule
├── createOrder()
├── payOrder()
└── cancelOrder()
بنابراین Table Module را میتوان در بسیاری از پروژهها یک نقطه میانی میان Transaction Script و Domain Model دانست. این الگو منطق را نسبت به Transaction Script منسجمتر میکند، اما مانند Domain Model برای هر رکورد یک Object مستقل ایجاد نمیکند. <Cite refs={["turn0search1","turn0search3"]} />
# پیادهسازی Table Module در PHP
برای مثال، یک جدول سفارشها را در نظر میگیریم:
CREATE TABLE orders (
id INT AUTO_INCREMENT PRIMARY KEY,
user_id INT NOT NULL,
status VARCHAR(30) NOT NULL,
total INT NOT NULL,
created_at DATETIME NOT NULL
);
حالا میخواهیم یک کلاس به نام OrderTableModule ایجاد کنیم.
این کلاس عملیات مربوط به جدول orders را مدیریت میکند.
ساخت کلاس OrderTableModule
<?php
final class OrderTableModule
{
public function __construct(
private PDO $pdo
) {
}
public function findById(int $id): ?array
{
$statement = $this->pdo->prepare(
'SELECT * FROM orders WHERE id = :id'
);
$statement->execute([
'id' => $id,
]);
$order = $statement->fetch(PDO::FETCH_ASSOC);
return $order ?: null;
}
public function getPendingOrders(): array
{
$statement = $this->pdo->query(
"SELECT * FROM orders WHERE status = 'pending'"
);
return $statement->fetchAll(PDO::FETCH_ASSOC);
}
}
در این مثال، OrderTableModule مسئول منطق و عملیات مرتبط با جدول سفارشهاست.
استفاده از آن:
$module = new OrderTableModule($pdo);
$order = $module->findById(10);
$pendingOrders = $module->getPendingOrders();
# افزودن عملیات ایجاد سفارش
اکنون متدی برای ایجاد سفارش اضافه میکنیم:
public function create(
int $userId,
int $total
): int {
if ($total <= 0) {
throw new InvalidArgumentException(
'Order total must be greater than zero.'
);
}
$statement = $this->pdo->prepare(
'INSERT INTO orders
(user_id, status, total, created_at)
VALUES
(:user_id, :status, :total, :created_at)'
);
$statement->execute([
'user_id' => $userId,
'status' => 'pending',
'total' => $total,
'created_at' => date('Y-m-d H:i:s'),
]);
return (int) $this->pdo->lastInsertId();
}
حالا:
$orderId = $module->create(
userId: 15,
total: 3500000
);
در اینجا قانون حداقل مبلغ سفارش نیز داخل Table Module قرار گرفته است.
# افزودن منطق لغو سفارش
فرض کنیم سفارش فقط زمانی قابل لغو است که وضعیت آن pending باشد.
public function cancel(int $id): void
{
$order = $this->findById($id);
if (!$order) {
throw new RuntimeException(
'Order not found.'
);
}
if ($order['status'] !== 'pending') {
throw new RuntimeException(
'Only pending orders can be cancelled.'
);
}
$statement = $this->pdo->prepare(
"UPDATE orders
SET status = 'cancelled'
WHERE id = :id"
);
$statement->execute([
'id' => $id,
]);
}
استفاده:
$module->cancel(10);
در این طراحی Controller نیازی ندارد جزئیات وضعیت سفارش را بررسی کند.
# محاسبه فروش روزانه در Table Module
یکی از کاربردهای Table Module مدیریت منطق مربوط به مجموعهای از رکوردهاست.
برای مثال، محاسبه فروش روزانه:
public function calculateDailySales(
string $date
): int {
$statement = $this->pdo->prepare(
"SELECT COALESCE(SUM(total), 0)
FROM orders
WHERE status = 'paid'
AND DATE(created_at) = :date"
);
$statement->execute([
'date' => $date,
]);
return (int) $statement->fetchColumn();
}
استفاده:
$total = $module->calculateDailySales(
'2026-09-17'
);
echo $total;
این نوع منطق به مجموعهای از سفارشها مربوط است، نه فقط یک سفارش مشخص.
به همین دلیل قرار دادن آن در Table Module میتواند طبیعی باشد.
# استفاده از Table Data Gateway
در بسیاری از طراحیها بهتر است ارتباط مستقیم با دیتابیس از منطق کسبوکار جدا شود.
در این حالت میتوان یک OrderTableGateway ایجاد کرد.
<?php
final class OrderTableGateway
{
public function __construct(
private PDO $pdo
) {
}
public function findById(int $id): ?array
{
$statement = $this->pdo->prepare(
'SELECT * FROM orders WHERE id = :id'
);
$statement->execute([
'id' => $id,
]);
$order = $statement->fetch(PDO::FETCH_ASSOC);
return $order ?: null;
}
public function updateStatus(
int $id,
string $status
): void {
$statement = $this->pdo->prepare(
'UPDATE orders
SET status = :status
WHERE id = :id'
);
$statement->execute([
'id' => $id,
'status' => $status,
]);
}
}
حالا Table Module میتواند از Gateway استفاده کند:
<?php
final class OrderTableModule
{
public function __construct(
private OrderTableGateway $orders
) {
}
public function cancel(int $id): void
{
$order = $this->orders->findById($id);
if (!$order) {
throw new RuntimeException(
'Order not found.'
);
}
if ($order['status'] !== 'pending') {
throw new RuntimeException(
'Only pending orders can be cancelled.'
);
}
$this->orders->updateStatus(
id: $id,
status: 'cancelled'
);
}
}
در این ساختار:
- Gateway عملیات دیتابیس را انجام میدهد.
- Table Module قوانین کسبوکار را اجرا میکند.
Table Data Gateway به صورت طبیعی با Table Module هماهنگ میشود، زیرا هر دو حول ساختار جدولی دادهها طراحی شدهاند. <Cite refs={["turn0search21","turn0search1"]} />
# Table Module در Laravel
در Laravel میتوان این الگو را با Query Builder، Eloquent یا یک Gateway سفارشی پیادهسازی کرد.
برای مثال، ساختار زیر را در نظر بگیرید:
app/
├── Modules/
│ └── Orders/
│ ├── OrderTableModule.php
│ └── OrderTableGateway.php
│
└── Http/
└── Controllers/
└── OrderController.php
ساخت OrderTableModule در Laravel
<?php
namespace App\Modules\Orders;
use Illuminate\Support\Facades\DB;
use RuntimeException;
final class OrderTableModule
{
public function findById(int $id): ?object
{
return DB::table('orders')
->where('id', $id)
->first();
}
public function getPendingOrders(): array
{
return DB::table('orders')
->where('status', 'pending')
->get()
->all();
}
public function create(
int $userId,
int $total
): int {
if ($total <= 0) {
throw new RuntimeException(
'Order total must be greater than zero.'
);
}
return (int) DB::table('orders')->insertGetId([
'user_id' => $userId,
'status' => 'pending',
'total' => $total,
'created_at' => now(),
'updated_at' => now(),
]);
}
public function cancel(int $id): void
{
$order = $this->findById($id);
if (!$order) {
throw new RuntimeException(
'Order not found.'
);
}
if ($order->status !== 'pending') {
throw new RuntimeException(
'Only pending orders can be cancelled.'
);
}
DB::table('orders')
->where('id', $id)
->update([
'status' => 'cancelled',
'updated_at' => now(),
]);
}
}
در این مثال، Table Module به جای ساختن یک Object مستقل برای هر سفارش، عملیات مربوط به کل جدول orders را مدیریت میکند.
# استفاده از Table Module در Controller
Controller میتواند از Table Module استفاده کند:
<?php
namespace App\Http\Controllers;
use App\Modules\Orders\OrderTableModule;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
final class OrderController
{
public function __construct(
private OrderTableModule $orders
) {
}
public function store(Request $request): JsonResponse
{
$validated = $request->validate([
'user_id' => ['required', 'integer'],
'total' => ['required', 'integer', 'min:1'],
]);
$orderId = $this->orders->create(
userId: $validated['user_id'],
total: $validated['total']
);
return response()->json([
'id' => $orderId,
], 201);
}
public function cancel(int $id): JsonResponse
{
$this->orders->cancel($id);
return response()->json([
'message' => 'Order cancelled successfully.',
]);
}
}
Controller در اینجا فقط درخواست را دریافت و پاسخ را تولید میکند.
منطق مربوط به سفارشها در OrderTableModule قرار گرفته است.
# استفاده از تراکنش دیتابیس
اگر یک عملیات روی چند جدول اجرا میشود، بهتر است از تراکنش دیتابیس استفاده کنیم.
برای مثال، هنگام ثبت سفارش ممکن است نیاز داشته باشیم:
- سفارش ایجاد شود.
- آیتمهای سفارش ذخیره شوند.
- موجودی محصولات کاهش پیدا کند.
- تراکنش مالی ثبت شود.
در Laravel:
use Illuminate\Support\Facades\DB;
public function createOrder(
int $userId,
array $items
): int {
return DB::transaction(function () use (
$userId,
$items
) {
$orderId = DB::table('orders')->insertGetId([
'user_id' => $userId,
'status' => 'pending',
'total' => 0,
'created_at' => now(),
'updated_at' => now(),
]);
foreach ($items as $item) {
DB::table('order_items')->insert([
'order_id' => $orderId,
'product_id' => $item['product_id'],
'quantity' => $item['quantity'],
'price' => $item['price'],
]);
}
return $orderId;
});
}
در این مثال، Table Module میتواند فرآیند مربوط به جدول سفارشها و جدول آیتمهای سفارش را هماهنگ کند.
با این حال، اگر عملیات بیش از حد پیچیده شود، بهتر است Application Service یا Domain Model نیز وارد طراحی شوند.
# تفاوت Table Module و Repository
Repository معمولاً برای دسترسی به مجموعهای از Domain Objectها طراحی میشود.
مثلاً:
$order = $orderRepository->findById(10);
اما Table Module معمولاً علاوه بر دسترسی به داده، منطق کسبوکار مربوط به جدول را نیز مدیریت میکند:
$orderModule->cancel(10);
$orderModule->calculateDailySales($date);
Repository
تمرکز اصلی:
Find
Save
Delete
Search
Table Module
تمرکز اصلی:
Business Logic for a Table
Create Order
Cancel Order
Calculate Sales
Validate Table Rules
البته در پروژههای واقعی ممکن است Repository و Table Module در کنار یکدیگر استفاده شوند.
# تفاوت Table Module و Active Record
در Active Record معمولاً هر Object نماینده یک رکورد دیتابیس است.
برای مثال در Laravel:
$order = Order::find(10);
$order->status = 'paid';
$order->save();
اما در Table Module یک کلاس واحد میتواند روی تمام رکوردهای جدول کار کند:
$orderModule->findById(10);
$orderModule->cancel(10);
$orderModule->getPendingOrders();
Active Record معمولاً داده، رفتار مرتبط و عملیات Persistence را در یک Object ترکیب میکند.
Table Module بیشتر بر منطق مجموعهای از رکوردهای یک جدول تمرکز دارد.
# مزایای Table Module Pattern
۱. ساختار سادهتر نسبت به Domain Model
در پروژههایی که مدلسازی Objectهای مستقل برای هر رکورد ضروری نیست، Table Module میتواند سادهتر باشد.
۲. تمرکز منطق جدول در یک مکان
تمام Business Logic مربوط به جدول سفارشها در OrderTableModule قرار میگیرد.
۳. مناسب برای دادههای جدولی
اگر برنامه بیشتر با Record Setها، گزارشها و عملیات دستهجمعی کار میکند، این الگو میتواند طبیعی باشد.
۴. هماهنگی خوب با Table Data Gateway
Table Module و Table Data Gateway هر دو حول جدول دیتابیس طراحی میشوند و میتوانند به خوبی با یکدیگر ترکیب شوند. <Cite refs={["turn0search21","turn0search1"]} />
۵. کاهش تکرار Query و Business Rule
عملیات رایج مانند دریافت سفارشهای Pending یا محاسبه فروش روزانه میتوانند در یک کلاس متمرکز شوند.
# معایب Table Module Pattern
۱. بزرگ شدن کلاس
اگر جدول عملیات زیادی داشته باشد، Table Module ممکن است به یک کلاس بسیار بزرگ تبدیل شود.
۲. وابستگی به ساختار دیتابیس
در بسیاری از پیادهسازیها، Table Module مستقیماً با نام جدول و ستونهای دیتابیس کار میکند.
۳. دشواری در مدلسازی رفتارهای پیچیده هر Entity
اگر هر سفارش قوانین و رفتارهای پیچیده و متفاوتی داشته باشد، Domain Model ممکن است مناسبتر باشد.
۴. احتمال تبدیل شدن به کلاس همهکاره
اگر تمام گزارشها، عملیات دیتابیس، قوانین مالی، Notificationها و منطق خارجی در یک Table Module قرار بگیرند، طراحی بهمرور پیچیده میشود.
۵. تستهای وابسته به دیتابیس
اگر منطق کسبوکار مستقیماً به Query Builder یا PDO وابسته باشد، تست واحد آن دشوارتر از یک Domain Model مستقل خواهد بود.
# چه زمانی از Table Module استفاده کنیم؟
Table Module میتواند برای شرایط زیر مناسب باشد:
- پروژههای CRUD محور
- سیستمهای گزارشگیری
- سیستمهایی که دادهها بیشتر به صورت جدول مدیریت میشوند
- منطق ساده یا متوسط مربوط به یک جدول
- برنامههایی که از Record Set استفاده میکنند
- سیستمهای اداری و مالی ساده
- پروژههایی که Domain Model کامل برای آنها بیش از نیاز است
- عملیات دستهجمعی روی رکوردها
برای مثال، یک سیستم مدیریت سفارش ساده میتواند چنین ساختاری داشته باشد:
OrderTableModule
├── create()
├── update()
├── cancel()
├── findByUser()
└── calculateSales()
# چه زمانی از Table Module استفاده نکنیم؟
اگر هر Entity رفتارهای پیچیده و مستقل دارد، بهتر است Domain Model را بررسی کنیم.
برای مثال در یک سیستم بیمه، هر قرارداد ممکن است:
- شرایط متفاوت داشته باشد.
- قوانین محاسبه متفاوت داشته باشد.
- وضعیتهای پیچیده داشته باشد.
- به چند Entity دیگر وابسته باشد.
- رویدادهای Domain تولید کند.
در چنین شرایطی یک Table Module بزرگ ممکن است تمام این منطق را در یک کلاس جمع کند و نگهداری را دشوار سازد.
همچنین اگر هدف اصلی جداسازی کامل Domain از دیتابیس باشد، Data Mapper و Domain Model میتوانند انتخاب مناسبتری باشند.
# تست Table Module با PHPUnit
برای تست Table Module در Laravel میتوان از تستهای دیتابیسی استفاده کرد.
مثلاً:
<?php
namespace Tests\Feature;
use App\Modules\Orders\OrderTableModule;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Support\Facades\DB;
use Tests\TestCase;
final class OrderTableModuleTest extends TestCase
{
use RefreshDatabase;
public function test_it_can_create_an_order(): void
{
$module = app(OrderTableModule::class);
$orderId = $module->create(
userId: 1,
total: 2500000
);
$this->assertDatabaseHas('orders', [
'id' => $orderId,
'user_id' => 1,
'status' => 'pending',
'total' => 2500000,
]);
}
public function test_it_can_cancel_a_pending_order(): void
{
$orderId = DB::table('orders')->insertGetId([
'user_id' => 1,
'status' => 'pending',
'total' => 2500000,
'created_at' => now(),
'updated_at' => now(),
]);
$module = app(OrderTableModule::class);
$module->cancel($orderId);
$this->assertDatabaseHas('orders', [
'id' => $orderId,
'status' => 'cancelled',
]);
}
}
برای اجرای تست:
php artisan test --filter=OrderTableModuleTest
این نوع تست بیشتر رفتار Table Module را در کنار دیتابیس بررسی میکند.
# اشتباهات رایج در پیادهسازی Table Module
۱. قرار دادن تمام منطق برنامه در یک Table Module
Table Module باید مسئول منطق مرتبط با یک جدول یا View باشد، نه تمام سیستم.
۲. ترکیب بیش از حد Query و منطق خارجی
ارسال ایمیل، اجرای API خارجی و مدیریت پرداخت نباید بدون دلیل در همان کلاس قرار بگیرند.
۳. استفاده از Table Module برای Domain بسیار پیچیده
اگر قوانین هر Entity پیچیده هستند، Domain Model میتواند طراحی مناسبتری ارائه دهد.
۴. نادیده گرفتن تراکنشهای دیتابیس
اگر عملیات چند مرحلهای است، باید احتمال شکست در میانه عملیات را در نظر گرفت.
۵. نوشتن Queryهای تکراری در Controllerها
اگر یک Query یا قانون در چند Controller تکرار میشود، بهتر است به Table Module یا Gateway منتقل شود.
۶. نامگذاری مبهم کلاس
نامهایی مانند Helper یا CommonService مشخص نمیکنند کلاس چه مسئولیتی دارد.
نامی مانند:
OrderTableModule
واضحتر است.
# نمونه ساختار پیشنهادی در Laravel
برای پروژه متوسط میتوان از این ساختار استفاده کرد:
app/
└── Modules/
└── Orders/
├── OrderTableModule.php
├── OrderTableGateway.php
├── OrderValidator.php
└── Exceptions/
├── OrderNotFound.php
└── InvalidOrderStatus.php
اگر پروژه بزرگتر شد، میتوان Application Service را نیز اضافه کرد:
app/
├── Application/
│ └── Orders/
│ ├── CreateOrder.php
│ └── CancelOrder.php
│
├── Modules/
│ └── Orders/
│ ├── OrderTableModule.php
│ └── OrderTableGateway.php
│
└── Http/
└── Controllers/
└── OrderController.php
در این معماری:
- Controller مسئول HTTP است.
- Application Service جریان عملیات را هماهنگ میکند.
- Table Module منطق جدول را مدیریت میکند.
- Gateway به دیتابیس متصل میشود.
# جمعبندی
Table Module Pattern در PHP الگویی است که منطق کسبوکار مربوط به تمام ردیفهای یک جدول یا View را در یک کلاس واحد قرار میدهد.
در Domain Model معمولاً برای هر Entity یک Object مستقل داریم، اما در Table Module یک Object میتواند منطق تمام رکوردهای یک جدول را مدیریت کند. <Cite refs={["turn0search1","turn0search4"]} />
این الگو برای پروژههایی مناسب است که:
- دادههای آنها بیشتر جدولی هستند.
- Business Logic ساده یا متوسط است.
- عملیات دستهجمعی روی رکوردها اهمیت دارد.
- استفاده از Domain Model کامل بیش از نیاز پروژه است.
در مقابل، اگر رفتار هر Entity پیچیده و مستقل باشد، بهتر است Domain Model را بررسی کنیم.
در Laravel نیز میتوان Table Module را با Query Builder، Eloquent یا Table Data Gateway پیادهسازی کرد.
اصل مهم این است که الگو را متناسب با پیچیدگی واقعی پروژه انتخاب کنیم.
# سوالات متداول
Table Module Pattern در PHP چیست؟
Table Module Pattern الگویی است که منطق کسبوکار مربوط به تمام ردیفهای یک جدول یا View را در یک نمونه کلاس مدیریت میکند.
تفاوت Table Module و Domain Model چیست؟
در Domain Model معمولاً برای هر رکورد یک Object مستقل داریم، اما در Table Module یک Object منطق مربوط به تمام رکوردهای جدول را مدیریت میکند.
آیا Table Module برای Laravel مناسب است؟
بله. میتوان آن را با Query Builder، Eloquent یا یک Table Data Gateway در Laravel پیادهسازی کرد.
آیا Table Module همان Repository است؟
خیر. Repository بیشتر برای دسترسی به مجموعهای از Objectها استفاده میشود، اما Table Module علاوه بر دسترسی به داده، منطق کسبوکار مربوط به جدول را نیز مدیریت میکند.
Table Module با Table Data Gateway چه تفاوتی دارد؟
Table Data Gateway مسئول ارتباط با جدول دیتابیس است، اما Table Module مسئول اجرای Business Logic مربوط به آن جدول است.
آیا Table Module برای پروژههای CRUD مناسب است؟
بله. در پروژههای CRUD و سیستمهایی که منطق آنها حول جدولها شکل گرفته است، Table Module میتواند ساختار ساده و قابل فهمی ایجاد کند.
آیا در Table Module برای هر رکورد یک Object ساخته میشود؟
خیر. معمولاً یک نمونه از Table Module روی تمام رکوردهای جدول کار میکند.
چه زمانی بهتر است از Domain Model استفاده کنیم؟
وقتی هر Entity رفتارها و قوانین پیچیده و مستقل دارد، Domain Model معمولاً گزینه مناسبتری برای بررسی است.





