اصل تکمسئولیتی (Single Responsibility Principle) یعنی هر ماژول یا کامپوننت فقط یک دلیل برای تغییر داشته باشد. در پروژههای وب پیچیده، رعایت SRP باعث میشود کد قابل تستتر، قابل تغییرتر و خواناتر شود. تجربهٔ عملی: وقتی کد را به واحدهای کوچکتر با مسئولیت مشخص تقسیم میکنید، باگها راحتتر پیدا و ویژگیهای جدید سریعتر اضافه میشوند.
مثال فرانتاند (React)
کامپوننت بد: هم دیتا میگیرد، هم وضعیت مدیریت میکند، هم رندر میکند.
تقسیم به مسئولیتها: یک
این تقسیم باعث میشود تست hook و view جداگانه امکانپذیر و تغییر منطق دریافت داده بدون لمس رندر انجام شود.
مثال بکاند (Node.js / Express)
بهجای نوشتن منطق اعتبارسنجی، منطق تجاری و دسترسی به دیتابیس در یک فایل کنترلر، آنها را جدا کنید:
این ساختار واحدها را قابل تست میکند و تغییر در لایهٔ ذخیرهسازی تأثیر کمتری روی کنترلر دارد.
برای مرجع بیشتر منابعی مثل Refactoring.Guru و کتاب "Clean Code" پیشنهاد میشوند. نکتهٔ عملی: اگر نوشتن تست برای یک تابع سخت است، احتمالاً آن تابع بیش از یک مسئولیت دارد — آن را شکسته و ساده کنید.
🔖 #Web #وب #Frontend #Backend #clean_code #SRP #React #Node.js #refactoring #architecture #best_practices
👤 Developix
💎 Channel: @DevelopixWeb
مثال فرانتاند (React)
کامپوننت بد: هم دیتا میگیرد، هم وضعیت مدیریت میکند، هم رندر میکند.
function Dashboard(){
const [data,setData]=useState(null);
useEffect(()=>{fetch('/api/items').then(r=>r.json()).then(setData)},[]);
function save(item){fetch('/api/items', {method:'POST', body:JSON.stringify(item)})}
return <div>{data?.map(i=><div key={i.id}>{i.name}</div>)}</div>
}تقسیم به مسئولیتها: یک
useFetch hook و یک Presentational کامپوننت:
function useFetch(url){
const [data,setData]=useState(null);
useEffect(()=>{fetch(url).then(r=>r.json()).then(setData)},[url]);
return data;
}
function DashboardView({data}){ return <div>{data?.map(i=><div key={i.id}>{i.name}</div>)}</div> }
function Dashboard(){ const data=useFetch('/api/items'); return <DashboardView data={data}/> }این تقسیم باعث میشود تست hook و view جداگانه امکانپذیر و تغییر منطق دریافت داده بدون لمس رندر انجام شود.
مثال بکاند (Node.js / Express)
بهجای نوشتن منطق اعتبارسنجی، منطق تجاری و دسترسی به دیتابیس در یک فایل کنترلر، آنها را جدا کنید:
// controller
async function createItem(req,res){ const item=await itemService.create(req.body); res.json(item) }
// service
async function create(data){ validate(data); return repository.insert(data) }
این ساختار واحدها را قابل تست میکند و تغییر در لایهٔ ذخیرهسازی تأثیر کمتری روی کنترلر دارد.
برای مرجع بیشتر منابعی مثل Refactoring.Guru و کتاب "Clean Code" پیشنهاد میشوند. نکتهٔ عملی: اگر نوشتن تست برای یک تابع سخت است، احتمالاً آن تابع بیش از یک مسئولیت دارد — آن را شکسته و ساده کنید.
🔖 #Web #وب #Frontend #Backend #clean_code #SRP #React #Node.js #refactoring #architecture #best_practices
👤 Developix
💎 Channel: @DevelopixWeb
👍7❤1👎1🔥1
تمیز کردن Controller با تکنیک Extract Function 🧹
یکی از سادهترین و تاثیرگذارترین تکنیکهای refactor در وب، مخصوصاً توی backend، Extract Function هست: جدا کردن بخشهای منطقیِ یک تابع بزرگ به چند تابع کوچک، واضح و قابل تست. 👌
وقتی یک controller یا handler همهچیز را خودش انجام میدهد (validation، لاگ، query، mapping، ارسال response)، سریع تبدیل به کد شلوغ و سختقابلتغییر میشود؛ همون چیزی که تو Clean Code بهش میگن God Function یا Long Method.
بیایید یک مثال Node.js & Express ببینیم.
قبل از Extract Function (کد شلوغ)
این تابع "کار میکند"، اما:
• چندین سطح responsibility قاطی شده 🔥
• تست کردنش سختتر است
• توسعه بعدی (مثل اضافهکردن audit log یا event) ریسک bug دارد
بعد از Extract Function (کد تمیزتر)
الان هر تابع یک کار مشخص انجام میدهد:
•
•
•
چند مزیت مهم:
• تست واحد برای 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
یکی از سادهترین و تاثیرگذارترین تکنیکهای 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
👍3❤1