پرش به مطلب اصلی

سادگی (Simplicity)

سادگی یکی از بنیادی‌ترین اصول فلسفه‌ی توسعه در این پروژه است. هدف از این اصل، کاهش پیچیدگی‌های غیرضروری و ایجاد راه‌حل‌هایی است که قابل‌درک، قابل‌نگهداری و پایدار باشند.

سادگی به معنای «ابتدایی بودن» نیست؛ بلکه به معنای انتخاب مؤثرترین و کم‌هزینه‌ترین راه‌حل ممکن است که نیاز واقعی را برطرف کند، بدون افزودن ساختار یا abstractionهای غیرضروری.


چرا سادگی اهمیت دارد؟

سادگی در توسعه نرم‌افزار مزایای مهمی به همراه دارد:

  • کاهش هزینه‌های نگهداری
  • افزایش خوانایی و درک سریع کد
  • کاهش احتمال خطاهای غیرمنتظره
  • افزایش تست‌پذیری
  • ایجاد ساختار پایدار و توسعه‌پذیر
  • جلوگیری از انباشت پیچیدگی (Complexity Debt)

سیستمی که ساده طراحی شود، بهتر مقیاس می‌گیرد و کمتر نیازمند بازنویسی خواهد بود.


اصول کلیدی برای رسیدن به سادگی

در ادامه، مجموعه‌ای از اصول عملی ارائه شده است که رعایت آن‌ها به سادگی واقعی در کد و معماری کمک می‌کند.

از انتزاع‌های زودهنگام پرهیز کنید

نمونه نامناسب
export const BaseInteractiveElement = ({ as: Component, ...props }) => {
return <Component {...props} />
}

export const Button = (props) => {
return <BaseInteractiveElement as='button' {...props} />
}

این الگو باعث پیچیدگی و کاهش خوانایی می‌شود.

نمونه مناسب
export const Button = (props) => {
return <button className='primary' {...props} />
}

یک تابع تنها یک مسئولیت داشته باشد

توابع چندمنظوره خوانایی و تست‌پذیری را کاهش می‌دهند.

نمونه نامناسب
const submitForm = (form) => {
const validateForm = (form) => {}
const buildPayload = (form) => {}

const isValid = validateForm(form)
if (!isValid) {
toast.error('Invalid data')
return
}

const payload = buildPayload(form)

return api.post('/submit', payload)
}
نمونه مناسب
const validateForm = (form) => {}
const buildPayload = (form) => {}
const sendSubmitRequest = (payload) => {}

const submitForm = (form) => {
if (!validateForm(form)) return
return sendSubmitRequest(buildPayload(form))
}

کد هوشمندانه لزوماً ساده نیست

نمونه نامناسب
Object.fromEntries(items.map((i) => [i.id, i]))
نمونه مناسب
const map = {}
for (const item of items) {
map[item.id] = item
}

از تو در تویی زیاد اجتناب کنید

نمونه نامناسب
if (user && user.profile && user.profile.age > 18) {
/* Logic Block */
}
نمونه مناسب
if (!user?.profile) return
if (user.profile.age <= 18) return
/* Logic Block */

رفتار تابع باید قابل‌پیش‌بینی باشد

توابعی که داده ورودی را تغییر می‌دهند یا اثرات ضمنی ایجاد می‌کنند، ساده نیستند.

نمونه نامناسب (mutation)
const addItem = (item, list) => {
list.push(item)
return list
}
نمونه مناسب
const addItem = (item, list) => {
return [...list, item]
}

معماری باید حداقلی و در حد نیاز باشد

سادگی در معماری یعنی:

  • اضافه نکردن لایه‌های زائد
  • انتخاب ابزار مناسب
  • جلوگیری از over-engineering

نمونهٔ واقعی از ابزار نامناسب:

  • استفاده از Redux برای دو مقدار ساده
  • استفاده از React Query برای یک fetch ساده
  • استفاده از Zustand برای حالتی که useState کفایت می‌کند

چک‌لیست سادگی

پیش از نهایی‌کردن هر PR این موارد را بررسی کنید:

  • آیا این ساده‌ترین راه‌حل مؤثر است؟
  • آیا abstraction واقعاً لازم است؟
  • آیا می‌توان تابع را کوچک‌تر و شفاف‌تر کرد؟
  • آیا رفتار تابع کاملاً قابل‌پیش‌بینی است؟
  • آیا نام‌گذاری واضح و دقیق است؟
  • آیا یک توسعه‌دهنده جدید بدون توضیح کد را درک می‌کند؟

اگر حتی به یکی از سؤالات پاسخ «نه» باشد، کد هنوز ساده نیست.


جمع‌بندی

سادگی یک اصل بنیادین و یک ارزش بلندمدت است.

سادگی باعث:

  • افزایش کیفیت
  • کاهش هزینه
  • افزایش سرعت توسعه
  • ایجاد معماری پایدار می‌شود.

تمام اجزای سیستم باید تا حد امکان ساده، شفاف و قابل‌درک باشند.