صفحه فهرست سفارش به چند کامپوننت، یک فرم فیلتر و چند تابع دریافت داده نیاز دارد. اگر همه کامپوننتها را در یک پوشه و همه درخواستها را در فایل دیگری بگذاریم، شروع کار ساده است. اما کمی بعد، برای تغییر یک فیلد سفارش باید میان بخشهایی رفتوآمد کنیم که ارتباطشان فقط در ذهن نویسنده اولیه روشن است.
در بخش قبل، برای مسیرهای عمومی و خصوصی درباره رندر و تازگی داده تصمیم گرفتیم. حالا همان پنل را بر اساس قابلیتها سازمان میدهیم: سفارش، کاربر و اجزای واقعاً مشترک. پیشنیاز، شناخت کامپوننت و ماژول است؛ خروجی، مرز مسئولیت و قاعده وابستگی خواهد بود، نه یک درخت پوشه که بدون فکر به هر پروژه کپی شود.
قابلیت را از صفحه تشخیص دهیم
قابلیت سفارش فقط صفحه فهرست نیست. فیلترها، جزئیات، عملیات تغییر وضعیت و تفسیر خطاهای مربوط به سفارش هم به آن تعلق دارند. ممکن است این بخشها در چند مسیر نمایش داده شوند، اما درباره یک حوزه از کار محصول صحبت میکنند.
در مقابل، دکمه عمومی یا نشان بارگذاری لزوماً مفهوم سفارش را نمیشناسد. اگر دکمهای فقط رنگ و حالت غیرفعال را مدیریت میکند، میتواند مشترک باشد. اگر خودش تشخیص میدهد سفارش لغوشده قابل ارسال نیست، بخشی از رفتار قابلیت وارد آن شده و دیگر یک جزء عمومی ساده نیست.
همجواری را بر اساس دلیل تغییر بسنجیم
فرض کنید به سفارش وضعیت «در انتظار بستهبندی» اضافه میشود. برچسب وضعیت، فیلتر مربوط و بخشی از نمایش جزئیات احتمالاً با هم تغییر میکنند. نزدیکبودن این بخشها کمک میکند تغییر را کامل ببینیم. هدف این نیست که همهچیز در یک فایل باشد؛ میخواهیم ارتباط منطقی در ساختار قابل تشخیص شود.
این معیار را با نمونههای واقعی تغییر امتحان کنید. اگر یک قابلیت همیشه به اصلاح چند فایل در پوشههای کاملاً نامرتبط نیاز دارد، شاید مرز فعلی برای تیم روشن نیست. البته تعداد فایل معیار قطعی نیست؛ تغییر قرارداد عمومی میتواند بهطور طبیعی چند مصرفکننده داشته باشد.
| بخش | مسئولیت | نمونه محتوا |
|---|---|---|
| سفارش | رفتار و نمایش سفارش | فهرست، جزئیات، فیلتر و برچسب وضعیت |
| کاربر | جریانهای مرتبط با کاربر | پروفایل و تنظیمات حساب |
| رابط مشترک | اجزای مستقل از دامنه | دکمه، دیالوگ و ورودی پایه |
| زیرساخت فرانت | ارتباط و تنظیمات مشترک فنی | کلاینت HTTP و قرارداد خطای پایه |
مرز عمومی هر قابلیت را کوچک نگه داریم
مصرفکننده بیرونی نباید برای استفاده از قابلیت سفارش، مسیر داخلی چندین فایل را بداند. میتوان ورودی عمومی محدودی داشت که صفحه یا تابع موردنیاز را در اختیار بگذارد. این مرز به تیم اجازه میدهد داخل قابلیت را بدون اصلاح همه مصرفکنندهها مرتب کند.
اما یک فایل خروجی بزرگ که همه جزئیات را صادر میکند، مرز واقعی ایجاد نمیکند. مشخص کنید چه چیزی عمومی است و چرا. نوع دادهای که فقط برای وضعیت یک دیالوگ داخلی استفاده میشود، معمولاً لازم نیست قرارداد بقیه برنامه باشد.
دریافت داده و تفسیر آن را قاطی نکنیم
کلاینت HTTP میتواند هدر، زمان انتظار و خطای پایه ارتباط را مدیریت کند. اما معنای «این سفارش دیگر قابل ویرایش نیست» به قابلیت سفارش مربوط است. اگر همه قواعد در یک فایل عمومی درخواستها جمع شوند، آن فایل به محل تصمیمهای پراکنده دامنه تبدیل میشود.
در سمت دیگر، هر کامپوننت هم نباید شکل خام پاسخ را به شیوه خودش تفسیر کند. قرارداد دریافت و تبدیل داده را در مرز مشخص نگه دارید. وقتی یک فیلد از API تغییر کرد، معلوم باشد کدام بخش مسئول تطبیق است و کدام آزمون سازگاری را بررسی میکند.
قابلیتها را با واردکردن جزئیات هم گره نزنیم
فرض کنید صفحه سفارش نام مسئول رسیدگی را نشان میدهد. برای این نیاز، واردکردن کامپوننت داخلی تنظیمات پروفایل از قابلیت کاربر مناسب نیست. شاید یک نمایش کوچک مستقل یا داده خواندنی محدود کافی باشد. وابستگی باید به نیاز واقعی پاسخ دهد، نه اینکه از نزدیکترین فایل موجود استفاده کند.
اگر سفارش و کاربر دائماً به جزئیات یکدیگر وابسته میشوند، علت را بررسی کنید. شاید یک مفهوم مشترک کوچک وجود دارد؛ شاید هم هماهنگی باید در لایه مسیر انجام شود. انتقال همهچیز به پوشه مشترک، چرخه وابستگی را فقط پنهان میکند.
مرز سرور و مرورگر را در ساختار حفظ کنیم
همجواری فایلها به معنی یکسانبودن محیط اجرای آنها نیست. تابعی که به تنظیمات محرمانه سرور دسترسی دارد نباید از مسیر یک جزء مرورگری وارد بسته سمت کاربر شود. در ابزارهایی که مرز Server و Client دارند، قواعد همان ابزار را صریح رعایت کنید.
برای مثال، قابلیت سفارش میتواند هم دریافت داده سمت سرور و هم کنترل تعاملی فیلتر داشته باشد. وجود این دو در یک حوزه منطقی، مجوز ترکیب بیقیدشان نیست. نام و محل فایل باید به خواننده کمک کند محیط اجرا را تشخیص دهد و ابزار ساخت نیز باید وابستگی نامعتبر را بگیرد.
جزء مشترک را پس از شناخت مصرفکنندهها استخراج کنیم
دو کارت شبیه به هم ممکن است رفتار متفاوت داشته باشند. اگر زود آنها را با تعداد زیادی پرچم یکی کنیم، استفاده از جزء مشترک سختتر میشود. ابتدا تفاوتها را بشناسید؛ بخشی را مشترک کنید که قرارداد پایدار و قابل توضیح دارد.
راهنمای Thinking in React، شکستن رابط بر اساس مسئولیت و جریان داده را نشان میدهد. برای ساختار قابلیتمحور هم همین نگاه مفید است: جزء باید دلیل مشخصی برای وجود داشته باشد. تعداد پوشهها یا میزان اشتراک کد بهتنهایی نشان نمیدهد طراحی خوب شده است.
وضعیت صفحه را در نزدیکترین جای مناسب نگه داریم
بازبودن یک دیالوگ معمولاً به همان بخش رابط مربوط است. فیلتر قابل اشتراک ممکن است در URL قرار بگیرد. داده سفارش نیز چرخه تازگی و دریافت دوباره دارد. اگر همه اینها را به یک مخزن سراسری منتقل کنیم، مسئولیتها دوباره درهم میشوند.
در این قسمت کتابخانه مدیریت داده یا State انتخاب نمیکنیم. فقط مالکیت را مشخص میکنیم: چه کسی مقدار را تغییر میدهد و چه کسی آن را میخواند؟ بخشهای بعد تفاوت داده سرور، وضعیت رابط و URL را جداگانه باز خواهند کرد.
آزمونها را به رفتار قابلیت وصل کنیم
برای سفارش، مسیر مهم این است که فیلتر نتیجه درست بدهد، جزئیات سفارش انتخابی باز شود و تغییر وضعیت با نتیجه معتبر هماهنگ بماند. بخشی از این رفتار را میتوان در آزمون محدود قابلیت بررسی کرد؛ سفر کامل به آزمون مسیر و API واقعی هم نیاز دارد.
آزمونی که فقط وجود فایل یا نام پوشه را میسنجد، نگهداری را ثابت نمیکند. بهتر است هنگام تغییر یک قاعده، ببینیم آیا آزمون مربوط خطای معنادار را میگیرد. در این مقاله کد اجرایی ارائه نمیشود و سناریوها برنامه پیشنهادی بررسی ساختارند.
مهاجرت را با یک قابلیت شروع کنیم
اگر پروژه فعلی پوشههای عمومی بزرگ دارد، لازم نیست همه آن را یکجا جابهجا کنیم. قابلیت سفارش را انتخاب کنید، مرز عمومیاش را مشخص کنید و وابستگیهای داخلی را بهتدریج نزدیک هم بیاورید. تغییر رفتار و جابهجایی فایل را تا جای ممکن قابل تشخیص نگه دارید.
بعد از این کار، یک تغییر کوچک مانند افزودن فیلتر را امتحان کنید. آیا محل اصلاح روشنتر شده؟ آیا واردکردن جزئیات داخلی کمتر شده؟ پاسخ به این پرسشها از تمیزبودن تصویر درخت پروژه مهمتر است. اگر نتیجه بدتر شد، مرز انتخابی را بازبینی کنید.
تمرین و قدم بعدی
برای پنل نمونه، پنج جزء انتخاب کنید و کنار هرکدام بنویسید چه چیزی درباره سفارش یا کاربر میداند. مواردی که هیچ مفهوم دامنهای ندارند نامزد اشتراکاند؛ مواردی که قاعده سفارش را اجرا میکنند باید صاحب روشن داشته باشند. سپس یک قاعده برای وابستگی میان قابلیتها ثبت کنید.
در بخش بعد، پایه دیداری مشترک را میسازیم: رنگ، فاصله و اندازهها به Design Token تبدیل میشوند تا همجواری کد با یکپارچگی ظاهر همراه باشد. این اشتراک دیداری باید بدون کشاندن قواعد سفارش به اجزای عمومی انجام شود.
مرجع تکمیلی
Thinking in React در مستندات رسمی React برای تحلیل مسئولیت اجزا و جریان داده مفید است. ساختار پیشنهادی این مقاله، تصمیمی آموزشی برای پنل نمونه است و الزام خود React محسوب نمیشود.
