| کانال توسعه‌دهندگان وب |
3.09K subscribers
57 photos
2 videos
53 links
⭕️ کانال توسعه‌دهندگان وب دولوپیکس

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

💎 @Developix
🚀 Developix.ir

📌 پشتیبانی و تبلیغات:
@DevelopixSupport
Download Telegram
‏تمیز کردن Controller با تکنیک Extract Function 🧹

یکی از ساده‌ترین و تاثیرگذارترین تکنیک‌های refactor در وب، مخصوصاً توی backend، Extract Function هست: جدا کردن بخش‌های منطقیِ یک تابع بزرگ به چند تابع کوچک، واضح و قابل تست. 👌

وقتی یک controller یا handler همه‌چیز را خودش انجام می‌دهد (validation، لاگ، query، mapping، ارسال response)، سریع تبدیل به کد شلوغ و سخت‌قابل‌تغییر می‌شود؛ همون چیزی که تو Clean Code بهش می‌گن God Function یا Long Method.

بیایید یک مثال Node.js & Express ببینیم.

قبل از Extract Function (کد شلوغ)
app.post('/api/users', async (req, res) => {
const { email, password } = req.body;

if (!email || !password) {
return res.status(400).json({ message: 'Invalid data' });
}

console.log('Creating user', email);

const exists = await User.findOne({ email });
if (exists) {
return res.status(409).json({ message: 'User exists' });
}

const hash = await bcrypt.hash(password, 10);
const user = await User.create({ email, password: hash });

return res.status(201).json({
id: user.id,
email: user.email,
});
});


این تابع "کار می‌کند"، اما:

• چندین سطح responsibility قاطی شده 🔥
• تست کردنش سخت‌تر است
• توسعه بعدی (مثل اضافه‌کردن audit log یا event) ریسک bug دارد

بعد از Extract Function (کد تمیزتر)
function validateCreateUser(body) {
const { email, password } = body;
if (!email || !password) {
throw new Error('INVALID_DATA');
}
}

async function ensureUserNotExists(email) {
const exists = await User.findOne({ email });
if (exists) {
throw new Error('USER_EXISTS');
}
}

async function createUser(email, password) {
const hash = await bcrypt.hash(password, 10);
return User.create({ email, password: hash });
}

app.post('/api/users', async (req, res) => {
try {
validateCreateUser(req.body);

const { email, password } = req.body;
await ensureUserNotExists(email);

const user = await createUser(email, password);

return res.status(201).json({
id: user.id,
email: user.email,
});
} catch (err) {
if (err.message === 'INVALID_DATA') {
return res.status(400).json({ message: 'Invalid data' });
}
if (err.message === 'USER_EXISTS') {
return res.status(409).json({ message: 'User exists' });
}
return res.status(500).json({ message: 'Server error' });
}
});


الان هر تابع یک کار مشخص انجام می‌دهد:

validateCreateUser → فقط validation
ensureUserNotExists → فقط چک کردن business rule
createUser → فقط ساختن user

چند مزیت مهم:

• تست واحد برای validation و منطقِ وجود کاربر مستقل از Express
• خوانایی خیلی بهتر؛ controller مثل یک سناریو step-by-step شده 📖
• آماده‌ برای reuse در endpoint یا سرویس‌های دیگر ♻️

برای مطالعه بیشتر درباره Extract Function و refactoring:
refactoring.guru/extract-method

این نوع refactorهای کوچک، در طول زمان معماری backend و حتی frontend (مثلاً در handlerهای React/Next.js) را بسیار تمیزتر و قابل‌نگه‌داری‌تر می‌کند. امروز روی یک متد شلوغ امتحانش کنید و تفاوت را در خوانایی حس کنید. 🚀

🔖 #Web #وب #Frontend #Backend #refactoring #clean_code #nodejs #express #backend #extract_function #controller

👤 Developix

💎 Channel: @DevelopixWeb
👍31