اگر فکر کردی Clean Architecture (معماری پاک) فقط برای پروژه های غول آسای Java و C# ساخته شده و توی Flask باید همه چیز رو توی یک فایل app.py بریزی، سخت در اشتباهی. اتفاقاً توی Flask که یک میکرو فریمورک «آزاد» هست، اگر نظم نداشته باشی، پروژه ات خیلی زود تبدیل به یک کلاف سردرگم (Spaghetti Code) میشه که حتی خودت هم جرات نمیکنی بهش دست بزنی.
پیاده سازی Clean Architecture یعنی وقتی کارفرما میگه: «دیتابیس رو از PostgreSQL به MongoDB تغییر بده» یا «به جای وب، میخوام از CLI هم دستورات رو اجرا کنم»، تو به جای عرق سرد ریختن، با لبخند بگی: «نیم ساعت دیگه آمادست!».
لایهی قلب: Entities (دنیای بدون وابستگی)
توی این لایه، فقط منطق خالص بیزنس قرار داره. اینجا نه خبری از Flask هست، نه SQLAlchemy و نه هیچ کتابخانه ی خارجی دیگه. اینجا فقط پایتون خالصه.
چرا؟ چون منطق کسب و کار شما نباید به این بند باشه که فلان فریمورک آپدیت شده یا نه.
# domain/models.py
class User:
def __init__(self, id, email, password):
self.id = id
self.email = email
self.password = password
def is_valid_email(self):
return "@" in self.email
لایهی Use Cases: کارگردانهای سناریو
اینجا جاییه که مشخص میشه برنامه قراره چیکار کنه. مثلاً «ثبت نام کاربر». این لایه فقط میدونه که "چی" میخواد، اما نمیدونه "چطوری" انجام میشه. برای ذخیره کاربر، از یک Interface (مخزن) استفاده میکنه ولی کاری ندارد که این مخزن به دیتابیس وصله یا یک فایل متنی!
نکته طلایی: Use Case نباید بدونه دیتایی که میگیره از JSON میاد یا از فرمهای HTML. اون فقط ورودی رو میگیره و پردازش میکنه.
جادوی Repositories: دیتابیس زیر سلطهی شما
بزرگترین اشتباه در Flask اینه که کوئری های SQLAlchemy رو مستقیم توی Viewها بنویسی. در معماری پاک، ما یک Interface تعریف میکنیم. این یعنی دیتابیس شما به یک "جزئیات" تبدیل میشه که به راحتی قابل تعویضه.
# infrastructure/repositories.py
class SQLUserRepository:
def save(self, user):
db.session.add(user)
db.session.commit()
لایهی بیرونی: Flask فقط یک «جزئیات» است!
در Clean Architecture، فریمورک Flask فقط یک وسیله برای رساندن دیتا به کاربر (Delivery Mechanism) هست. Routeهای شما باید به شدت لاغر (Thin Controllers) باشن.
تلهی مرگبار: اگر توی تابع route داری رمزنگاری پسورد انجام میدی یا کوئری دیتابیس میزنی، داری راه رو اشتباه میری! راه حل:Route فقط ورودی رو میگیره، Use Case رو صدا میزنه و نتیجه رو برمیگردونه.
@app.route('/register', methods=['POST'])
def register():
data = request.json
# فراخوانی Use Case به جای نوشتن مستقیم منطق
use_case = RegisterUserUseCase(UserRepository())
user = use_case.execute(data['email'], data['password'])
return {"id": user.id}, 201
نفوذ به قلب سیستم با Dependency Injection
توی Flask برخلاف FastAPI، سیستم تزریق وابستگی (DI) داخلی نداریم. اما برای اینکه یک مهندس واقعی باشی، باید از پترن DI استفاده کنی. این کار باعث میشه موقع تست نویسی، به جای دیتابیس واقعی، یک دیتابیس جعلی (Mock) به برنامه تزریق کنی و تست ها رو با سرعت نور اجرا کنی.
میتونی از کتابخونه هایی مثل pinject یا dependency-injector استفاده کنی یا خیلی ساده، وابستگیها رو دستی پاس بدی.
تستنویسی: بیمهی عمر پروژه
وقتی معماری پاک داری، تست کردن مثل آب خوردن میشه:
-
Unit Tests: چون منطق بیزنس (Entities) به هیچ جا وصل نیست، بدون نیاز به دیتابیس تستشون میکنی.
-
Integration Tests: فقط ارتباط بین لایهها رو چک میکنی.
-
End-to-End: کل جریان رو با Flask چک میکنی.
اگر تستی نوشتی که برای اجرا شدنش حتماً باید دیتابیس واقعی بالا باشه، یعنی یک جای کارِ معماریت میلنگه!
نتیجهگیری
پیادهسازی Clean Architecture در Flask یعنی:
-
استقلال از فریمورک: اگر فردا خواستی به Django یا FastAPI کوچ کنی، ۹۰٪ کدهات دست نخورده باقی میمونه.
-
تستپذیری بالا: کد ها رو مثل قطعات لگو جدا میکنی و تست میزنی.
-
نگهداری آسان: پیدا کردن باگ توی لایه های مشخص، خیلی راحتتر از گشتن توی یک فایل ۳۰۰۰ خطیه.
یادت باشه، معماری خوب اولش وقت گیره، اما وقتی پروژه بزرگ شد و بقیه دارن زیر بار باگ ها غرق میشن، تو با خیالی راحت داری قهوه ات رو میخوری و فیچر های جدید اضافه میکنی.
نظرات کاربران (0)