Clean Architecture یا معماری تمیز رویکردی برای جدا نگه داشتن قواعد کسب‌وکار از فریم‌ورک، دیتابیس و جزئیات ارتباطی است. قانون اصلی Dependency Rule است: وابستگی‌های سورس کد باید به سمت لایه‌های داخلی و قوانین پایدارتر باشند.

نمونه فروشگاه: ثبت سفارش مستقل از ORM

Use Case ثبت سفارش باید بتواند از یک قرارداد Repository و درگاه پرداخت استفاده کند. اینکه برنامه با لاراول، جنگو، Go یا ASP.NET Core ارائه شده، نباید هسته قانون «سفارش بدون موجودی ثبت نشود» را عوض کند.

لایهمسئولیتمثال فروشگاه
Entity / Domainقواعد پایهOrder، OrderItem و Money
Use Case / Applicationجریان کاریPlaceOrder، CancelOrder
Interface / Portقراردادهای بیرونیOrderRepository و PaymentGateway
Infrastructure / Adapterجزئیات اجراEloquent، Django ORM، PostgreSQL
Transport / ControllerHTTP، CLI یا ConsumerCheckoutController

PHP

interface OrderRepository { public function save(Order $order): void; }
final class PlaceOrder {
    public function __construct(private OrderRepository $orders) {}
    public function execute(Order $order): void {
        $order->validateStock();
        $this->orders->save($order);
    }
}

Python

from typing import Protocol
class OrderRepository(Protocol):
    def save(self, order): ...
class PlaceOrder:
    def __init__(self, repo: OrderRepository): self.repo = repo
    def execute(self, order):
        order.validate_stock()
        self.repo.save(order)

Go

type OrderRepository interface { Save(context.Context, Order) error }
type PlaceOrder struct { Repo OrderRepository }
func (u PlaceOrder) Execute(ctx context.Context, order Order) error {
    if err := order.ValidateStock(); err != nil { return err }
    return u.Repo.Save(ctx, order)
}

C#

public interface IOrderRepository { Task SaveAsync(Order order); }
public sealed class PlaceOrder(IOrderRepository repo) {
    public async Task ExecuteAsync(Order order) {
        order.ValidateStock();
        await repo.SaveAsync(order);
    }
}

Java

interface OrderRepository { void save(Order order); }
final class PlaceOrder {
    private final OrderRepository repo;
    PlaceOrder(OrderRepository repo) { this.repo = repo; }
    void execute(Order order) {
        order.validateStock();
        repo.save(order);
    }
}

اشتباه رایج

معماری تمیز الزام به ساخت ده‌ها Interface برای هر جدول نیست. در برنامه کوچک ممکن است پیچیدگی اضافه ایجاد کند. ارزش آن زمانی بیشتر است که منطق دامنه مهم، چرخه عمر طولانی و چند منبع یا چند فریم‌ورک داشته باشید.

اصطلاحات مرتبط: معماری شش‌ضلعی، طراحی دامنه‌محور، ریپازیتوری پترن، تزریق وابستگی، اصول سالید، کلین کد.

برای تکمیل این بحث، صفحه معماری نرم‌افزار را نیز ببینید.