| کانال توسعه‌دهندگان جاوااسکریپت |
3.91K subscribers
54 photos
3 videos
36 links
⭕️ کانال توسعه‌دهندگان جاوااسکریپت دولوپیکس

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

💎 @Developix
🚀 Developix.ir

📌 پشتیبانی و تبلیغات:
@DevelopixSupport
Download Telegram
‌‎پاک‌سازی توابع با تکنیک «Early Return» در JavaScript 🚿

یکی از ساده‌ترین و مؤثرترین تکنیک‌های Clean Code در جاوااسکریپت، استفاده از Early Return است؛ یعنی به‌جای پیچوندن منطق داخل ifهای تودرتو، در همان اول تابع، شرایط نامعتبر را سریع برگردانیم.

این تکنیک توابع را:

• کوتاه‌تر و خواناتر می‌کند
• از Nested if‌های عمیق جلوگیری می‌کند
• باعث می‌شود مسیرهای خطا و edge caseها واضح‌تر دیده شوند


نمونه کد قبل از refactor (کد سخت‌خوان)
function createUser(data) {
if (data) {
if (data.email) {
if (data.password && data.password.length >= 8) {
// save to DB
return { ok: true, user: data };
} else {
return { ok: false, error: 'Weak password' };
}
} else {
return { ok: false, error: 'Email is required' };
}
} else {
return { ok: false, error: 'No data' };
}
}


این تابع کارش را انجام می‌دهد، اما هر شرط جدیدی که اضافه شود، عمق ifها بیشتر می‌شود و دیباگ سخت‌تر.


Refactor با Early Return
function createUser(data) {
if (!data) {
return { ok: false, error: 'No data' };
}

if (!data.email) {
return { ok: false, error: 'Email is required' };
}

if (!data.password || data.password.length < 8) {
return { ok: false, error: 'Weak password' };
}

// happy path
return { ok: true, user: data };
}


الان:

• هر شرط invalid در بالا «قطع» می‌شود 🔪
• مسیر اصلی (happy path) در انتها واضح و تمیز است
• اضافه‌کردن شرط جدید فقط یعنی اضافه کردن چند خط دیگر بالای happy path


نمونه در Express / Node.js 🌐
app.post('/login', async (req, res) => {
const { email, password } = req.body;

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

const user = await findUserByEmail(email);
if (!user) {
return res.status(404).json({ message: 'User not found' });
}

const valid = await comparePassword(password, user.passwordHash);
if (!valid) {
return res.status(401).json({ message: 'Invalid password' });
}

// happy path
res.json({ token: createToken(user) });
});


هر مرحله نامعتبر به‌سرعت return می‌شود و منطق login مثل یک «چک‌لیست» خطی خوانده می‌شود.

نکته مهم 🔍

Early Return با Single Responsibility خیلی خوب جفت می‌شود؛ اگر تابع خیلی طولانی شد، علاوه بر early return، آن را به چند تابع کوچک‌تر با نام‌های خوب بشکنید.

منابع برای مطالعهٔ بیشتر:
MDN – Control Flow
Refactoring.Guru

این سبک نوشتن را کم‌کم در هندلرهای Express، سرویس‌های Node.js یا حتی توابع React خودتان وارد کنید؛ بعد از مدتی، خواندن و نگه‌داری کد برای خودتان و تیم‌تان به‌وضوح راحت‌تر می‌شود 🙌

🔖 #Javascript #JS #جاوااسکریپت #clean_code #early_return #javascript #nodejs #express #refactoring

👤 Developix

💎 Channel: @DevelopixJavascript
👍43
قانون «یک سطح انتزاع در هر تابع» در JavaScript 🧠

یکی از نکات طلایی در Clean Code این است که هر تابع فقط با یک سطح انتزاع کار کند. یعنی یا درگیر جزئیات low-level باشد، یا فقط کارهای high-level را صدا بزند؛ نه هر دو را قاطی.

این قانون کمک می‌کند:

• خوانایی کد بالا برود 👀
• Refactor کردن ساده‌تر شود 🔧
• تست‌نویسی راحت‌تر شود

🍂 یک مثال از کد شلوغ در Node.js / Express

app.post('/api/users', async (req, res) => {
const { email, password } = req.body;

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

if (!email.includes('@')) {
return res.status(400).json({ message: 'Invalid email' });
}

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

const hash = await bcrypt.hash(password, 10);

const user = {
email,
password: hash,
createdAt: new Date()
};

await db.collection('users').insertOne(user);

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


این تابع هم validation انجام می‌دهد، هم کار دیتابیس، هم جزئیات hash، هم پاسخ HTTP. سطح‌های انتزاع قاطی شده‌اند.

🌱 Refactor با یک سطح انتزاع در هر تابع

const validateUserPayload = (body) => {
const { email, password } = body;
if (!email || !password) return 'Invalid data';
if (!email.includes('@')) return 'Invalid email';
return null;
};

const createUser = async ({ email, password }, db, hasher) => {
const exists = await db.collection('users').findOne({ email });
if (exists) return { error: 'Already exists' };

const passwordHash = await hasher(password);

const user = {
email,
password: passwordHash,
createdAt: new Date()
};

const result = await db.collection('users').insertOne(user);

return { id: result.insertedId, email: user.email };
};

app.post('/api/users', async (req, res) => {
const validationError = validateUserPayload(req.body);
if (validationError) {
return res.status(400).json({ message: validationError });
}

const result = await createUser(
req.body,
db,
(password) => bcrypt.hash(password, 10)
);

if (result.error) {
return res.status(409).json({ message: result.error });
}

res.status(201).json(result);
});


حالا:

• تابع validateUserPayload فقط validation است
• تابع createUser فقط منطق ساخت کاربر را دارد
• route handler فقط orchestration انجام می‌دهد

این جداسازی باعث می‌شود بعداً راحت‌تر TypeScript اضافه کنید، Unit Test بنویسید، یا منطق ساخت کاربر را در سرویس دیگری (مثلاً در یک worker) استفاده کنید.

منابع برای مطالعه بیشتر:
Refactoring.Guru
MDN – Learn JS

قدم‌به‌قدم همین الگو را روی قسمت‌های شلوغ پروژه‌های Node.js / React / Next.js خود پیاده کنید؛ هر بار که یک تابع را به یک سطح انتزاع محدود می‌کنید، کدتان قابل‌اعتمادتر و نگه‌داری‌پذیرتر می‌شود 🚀

🔖 #Javascript #JS #جاوااسکریپت #Clean_Code #JavaScript #Node_js #Express #Refactoring #Best_Practices

👤 Developix

💎 Channel: @DevelopixJavascript
👍43👎3
اصل مهمی در Clean Code این است که هر تابع فقط یک وظیفهٔ واضح داشته باشد

وقتی یک تابع چند کار مختلف انجام می‌دهد:
- تست‌نویسی سخت می‌شود
- احتمال باگ بالا می‌رود
- خواندن و تغییر کد زمان‌بر می‌شود

به این ایده در Design Principleها می‌گویند: Single Responsibility Principle (SRP).

نمونهٔ یک تابع شلوغ در Node.js 👇
const registerUser = async (req, res) => {
const { email, password } = req.body;

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

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

// hash password
const bcrypt = await import('bcrypt');
const hashed = await bcrypt.hash(password, 10);

// save user
const user = await User.create({ email, password: hashed });

// send welcome email
await sendWelcomeEmail(email);

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

این تابع هم اعتبارسنجی می‌کند، هم دیتابیس می‌زند، هم ایمیل می‌فرستد؛ یعنی چند مسئولیت در یک جا.

حالا همان منطق را با توابع کوچک‌تر تمیزتر می‌کنیم 🧼
const validateRegisterInput = ({ email, password }) => {
if (!email || !password) return 'Email and password are required';
if (password.length < 8) return 'Password too short';
return null;
};

const ensureEmailUnique = async (email) => {
const existing = await User.findOne({ email });
if (existing) throw new Error('EMAIL_TAKEN');
};

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

const registerUser = async (req, res) => {
const { email, password } = req.body;

const error = validateRegisterInput({ email, password });
if (error) return res.status(400).json({ message: error });

try {
await ensureEmailUnique(email);
const user = await createUser({ email, password });
await sendWelcomeEmail(email);

return res.status(201).json({ id: user.id, email: user.email });
} catch (err) {
if (err.message === 'EMAIL_TAKEN') {
return res.status(409).json({ message: 'Email exists' });
}
return res.status(500).json({ message: 'Server error' });
}
};

حالا:
- تست کردن validateRegisterInput و createUser مستقل و ساده است
- تغییر قانون پسورد، فقط در یک تابع انجام می‌شود
- خطاها واضح‌تر و قابل مدیریت‌تر هستند

برای کدهای React، Express، Next.js و هر محیط JavaScript/TypeScript دیگر همین ایده جواب می‌دهد: توابع کوچک، با نام خوب و یک کار مشخص.

برای مطالعهٔ بیشتر می‌توان از Refactoring.Guru و MDN کمک گرفت.

قدم‌های کوچک refactor کردن همین امروز روی یکی از فانکشن‌های شلوغ پروژه، بعد از چند هفته تاثیر زیادی در خوانایی و کیفیت کد می‌گذارد 🚀

🔖 #Javascript #JS #جاوااسکریپت #JavaScript #Clean_Code #Node_js #Refactoring #SRP

👤 Developix

💎 Channel: @DevelopixJavascript
👍71