| کانال توسعه‌دهندگان وب |
3.07K subscribers
47 photos
1 video
44 links
⭕️ کانال توسعه‌دهندگان وب دولوپیکس

💠 دولوپیکس | جامعه توسعه‌دهندگان ایرانی

💎 @Developix
🚀 Developix.ir

📌 پشتیبانی و تبلیغات:
@DevelopixSupport
Download Telegram
‏Clean Architecture در یک سرویس ساده Node.js 🧱

یکی از مشکل‌های همیشگی پروژه‌های وب این است که بعد از چند ماه، همه‌چیز توی یک فایل یا یک لایه قاطی می‌شود: route منطق بیزینسی دارد، مستقیم به DB وصل می‌شود و تست‌ گرفتن هم کابوس می‌شود.

اینجا جایی است که ایدهٔ Clean Architecture به‌درد می‌خورد: جداکردن منطق بیزینسی از زیرساخت (مثل Express، DB، HTTP، و غیره) تا کد قابل‌تست و قابل‌توسعه بماند. 🎯

در ساده‌ترین حالت، فقط همین اصل را رعایت کنید:
Use Case / Domain لایهٔ مرکزی ➜ Framework و DB در لبه‌ها

یعنی:
• Route فقط ورودی/خروجی HTTP را مدیریت کند
• منطق اصلی در یک Service یا Use Case مستقل باشد
• Service هیچ وابستگی مستقیم به Express یا driver خاص DB نداشته باشد

یک نمونهٔ خیلی ساده در Node.js + Express:

// userService.js (لایه Domain / Use Case)
class UserService {
constructor(userRepo) {
this.userRepo = userRepo; // وابستگی به interface، نه به Express
}

async registerUser(data) {
const { email, password } = data;

if (!email || !password) {
throw new Error("Invalid data");
}

const exists = await this.userRepo.findByEmail(email);
if (exists) {
throw new Error("Email already used");
}

// اینجا می‌توانید hashing، ruleها و ... را قرار دهید
return this.userRepo.create({ email, password });
}
}

module.exports = UserService;


حالا لایهٔ زیرساخت (Express + یک repo ساده):

// userRepo.js (لایه Infrastructure)
const users = [];

module.exports = {
async findByEmail(email) {
return users.find(u => u.email === email) || null;
},
async create(user) {
users.push(user);
return user;
}
};

// routes.js
const express = require("express");
const UserService = require("./userService");
const userRepo = require("./userRepo");

const router = express.Router();
const userService = new UserService(userRepo);

router.post("/register", async (req, res) => {
try {
const user = await userService.registerUser(req.body);
res.status(201).json(user);
} catch (err) {
res.status(400).json({ error: err.message });
}
});

module.exports = router;


چند نکتهٔ عملی از تجربهٔ پروژه‌های واقعی 🌱

• منطق اصلی را همیشه در Service / Use Case نگه دارید، نه داخل controller / route.
• وابستگی‌ها را به‌سمت لبه‌ها ببرید؛ Domain نباید Express، HTTP status code یا driver خاص DB را بشناسد.
• این ساختار روی Next.js API Routes، Nest.js، Laravel و Django هم کاملاً قابل‌پیاده‌سازی است.

برای مطالعهٔ عمیق‌تر ایده‌ها:
Layered Architecture - Martin Fowler
Refactoring.Guru - Design Patterns

همان‌قدر که پروژه بزرگ‌تر می‌شود، همین جداسازی ساده بین Domain و Infrastructure می‌تواند نجات‌دهنده باشد. دفعهٔ بعدی که یک feature جدید می‌نویسید، از همین الگوی کوچک شروع کنید و قدم‌به‌قدم کد را تمیزتر نگه دارید. 🚀

🔖 #Web #وب #Frontend #Backend #Clean_Architecture #Node_js #Express #Design_Patterns #Web_Development #Backend #Refactoring

👤 Developix

💎 Channel: @DevelopixWeb
1