ہر ڈویلپر کے پاس وہ فولڈر ہوتا ہے۔ وہ جسے utils یا helpers کہا جاتا ہے اور جسے آپ ایک ریپوزٹری سے دوسری میں کاپی کرتے ہیں۔ آپ اسے پیسٹ کرتے ہیں، بیس منٹ پرانے ڈیٹا بیس اسکیما کے حوالے ختم کرنے میں، غیر متعلقہ آتھ (auth) چیکز نکالنے میں، اور ویری ایبلز کے نام بدلنے میں وقت گزارتے ہیں تاکہ آپ کا نیا لنٹر (linter) چیخنا بند کر دے۔ میں پہلے ایسا ہی کرتا تھا جب میں نے اپنا تھیمنگ سسٹم، ڈائنامک تھیم کٹ (Dynamic Theme Kit) بنایا تھا۔ اس کا آغاز ایک ایپلی کیشن کے اندر ایک فیچر کے طور پر ہوا تھا، اور مہینوں تک، میں نے اسے ایک پورٹیبل ٹول کے طور پر استعمال کیا۔ میں غلط تھا۔ کوڈ کاپی کرنا دوبارہ استعمال (reuse) نہیں ہے۔ یہ اضافی مراحل کے ساتھ تکرار (duplication) ہے۔
سنگل پروجیکٹ مائنڈ سیٹ کا جال
جب آپ کسی پروجیکٹ کے اندر کوئی فیچر بناتے ہیں، تو آپ سینکڑوں غیر مرئی مفروضے قائم کر لیتے ہیں۔ کلر پیلیٹ (color palette) شاید کسی خاص CSS-in-JS سیٹ اپ کا فرض کر رہا ہو۔ اسپیسنگ اسکیل (spacing scale) شاید آپ کی کمپنی کی برانڈ گائیڈ کے کسی ڈیزائن ٹوکن کا حوالہ دے رہا ہو۔ لائٹ اور ڈارک موڈ کے درمیان سوئچ شاید اس ایپ کے بیک اینڈ کے لیے مخصوص یوزر پریفرنس اینڈ پوائنٹ کو کال کر رہا ہو۔ یہ انحصار (dependencies) بے ضرر محسوس ہوتے ہیں کیونکہ پروجیکٹ کے اندر وہ بے ضرر ہی ہوتے ہیں۔ وہ وہیں کے لیے بنے ہوتے ہیں۔
مسئلہ تب شروع ہوتا ہے جب آپ اس کوڈ کو الگ کرنے کی کوشش کرتے ہیں۔ آپ کو معلوم ہوتا ہے کہ وہ "دوبارہ استعمال کے قابل" (reusable) کمپوننٹ دراصل پوشیدہ تعلقات کا ایک جال ہے جو اسے اس ایک کوڈ بیس سے جوڑے ہوئے ہے۔ میں نے یہ DTK کے ساتھ سیکھا۔ اس نے تھیم ویری ایبلز تو جنریٹ کیے، لیکن اس نے ایک مخصوص فولڈر اسٹرکچر کی بھی توقع کی۔ اس نے اصل ایپ کی ٹائپس ڈائریکٹری میں کہیں گہرائی سے ایک ٹائپ ڈیفینیشن (type definition) امپورٹ کی۔ اس نے ایک گلوبل کنفیگ آبجیکٹ کی موجودگی کا فرض کیا جو صرف اسی ایک ریپوزٹری میں موجود تھا۔ میں نے کبھی اس پر غور نہیں کیا تھا کیونکہ اس پروجیکٹ کے اندر، ہر چیز ہمیشہ موجود تھی۔
DTK کو ایک اسٹینڈ الون (standalone) پیکیج میں تبدیل کرنے کا مطلب توسیع نہیں بلکہ سرجری تھی۔ مجھے مزید فیچرز کی ضرورت نہیں تھی، بلکہ مجھے کم سے کم تعلقات (connections) کی ضرورت تھی۔
ڈائنامک تھیم کٹ (Dynamic Theme Kit) کو الگ کرنا
سب سے مشکل کام کوڈ بیس کے ساتھ بیٹھ کر ہر فنکشن اور ہر ایکسپورٹ سے یہ پوچھنا تھا کہ: کیا یہ تھیمنگ لاجک کے کام آتا ہے، یا یہ پروجیکٹ کے کام آتا ہے؟ میں نے اسٹائلنگ پری سیٹس (styling presets) نکال دیے۔ میں نے اس فرض کو ختم کر دیا کہ استعمال کرنے والا ایک React ایپلی کیشن ہوگی۔ میں نے ڈیفالٹ کلر پیلیٹس کو مکمل طور پر حذف کر دیا۔ اصل پروجیکٹ کے ڈیفالٹس میں ایک نیوی اور سلیکٹ کارپوریٹ جمالیات (aesthetic) شامل تھی۔ اسے ختم کرنا ضروری تھا۔ ایک پیکیج آپ کے برانڈ کلرز فراہم نہیں کر سکتا۔
نیا کٹ صرف ایک کام کرے گا۔ یہ ایک کنفیگریشن آبجیکٹ لے گا—کچھ کلر ویلیوز، کچھ اسپیسنگ نمبرز، کچھ ٹائپوگرافی اسکیلز—اور CSS کسٹم پراپرٹیز جنریٹ کرے گا۔ بس اتنا ہی۔ یہ انہیں اپلائی نہیں کرتا۔ یہ فیصلہ نہیں کرتا کہ وہ آپ کے DOM میں کہاں جائیں گے۔ اسے اس سے فرق نہیں پڑتا کہ آپ Tailwind، Styled Components، یا سادہ HTML استعمال کر رہے ہیں۔ یہ آپ کی ایپلی کیشن کو ویری ایبلز فراہم کرتا ہے، اور آپ کا پروجیکٹ فیصلہ کرتا ہے کہ انہیں کیسے استعمال کرنا ہے۔
وہ پابندی شروع میں محدود کرنے والی محسوس ہوئی، لیکن بعد میں یہ آزادی کا باعث بنی۔
جب آپ واقعی اسے دوبارہ استعمال کرنے کی کوشش کرتے ہیں تو کیا ٹوٹتا ہے
کچھ بھی شائع کرنے سے پہلے، مجھے اس بات کا ثبوت چاہیے تھا کہ یہ ایبسٹریکشن (abstraction) واقعی کارآمد ہے۔ میں نے اپنے آرکائیو سے تین چھوٹے ذاتی پروجیکٹس نکالے: ایک مارک ڈاؤن پری ویو ٹول (markdown preview tool)، ایک ہیبیٹ ٹریکر (habit tracker)، اور ایک ایونٹ کے لیے لینڈنگ پیج۔ ان میں سے کوئی بھی ایک ہی فریم ورک یا فولڈر اسٹرکچر شیئر نہیں کرتا تھا۔ میں نے ہر ایک میں مقامی طور پر DTK انسٹال کیا اور انہیں تھیم کرنے کی کوشش کی۔
پہلی کوشش فوراً ناکام ہوگئی۔ DTK کے ذریعے جنریٹ ہونے والے ویری ایبل کے نام بہت مخصوص تھے۔ یہ --primary-action اور --background-overlay جیسے ٹوکنز آؤٹ پٹ کر رہا تھا جو ایک خاص UI لے آؤٹ کا اشارہ دیتے تھے۔ مارک ڈاؤن پری ویور میں، ان ناموں کا کوئی مطلب نہیں تھا۔ وہاں کوئی ایکشن بٹن نہیں تھا۔ کوئی اوورلے (overlay) نہیں تھا۔ میں نے جنریشن لاجک کو دوبارہ لکھا تاکہ وہ غیر جانبدار، ساختی نام (structural names) پیدا کرے جو ویجیٹ کے بجائے ویلیو کی وضاحت کریں۔
میں نے یہ بھی محسوس کیا کہ میری ڈیفالٹ ویلیوز بہت زیادہ جارحانہ (aggressive) تھیں۔ جب کوئی صارف نامکمل کنفیگ پاس کرتا، تو DTK ان خالی جگہوں کو ایسی ویلیوز سے بھر دیتا جو ایک گھنے ڈیش بورڈ میں تو ٹھیک لگتی تھیں لیکن ایک سادہ لینڈنگ پیج پر خراب ہو جاتی تھیں۔ میں نے ٹرانسپیرنٹ ڈیفالٹس (transparent defaults) پر سوئچ کر دیا جہاں غائب ٹوکنز صرف رینڈر نہیں ہوتے تھے، جس سے استعمال کرنے والا پروجیکٹ اپنے خود کے فال بیکس (fallbacks) متعین کر سکتا تھا۔
پھر بات آتی ہے ڈاکومنٹیشن کی۔ جو بات میرے لیے واضح تھی—"بس ایک کنفیگریشن آبجیکٹ پاس کریں"—وہ آدھی رات کو README پڑھنے والے کے لیے مبہم تھی۔ میں نے اسے حقیقی آبجیکٹس، حقیقی فائل پاتھز، اور اس بات کی واضح وضاحت کے ساتھ دوبارہ لکھا کہ جب آپ فنکشن کال کرتے ہیں تو کیا ہوتا ہے اور اس کے بعد آپ کی ایپلی کیشن کو کیا کرنے کی ضرورت ہے۔
یہ چھوٹے ذاتی پروجیکٹس ٹیسٹ بیڈز (test beds) کے طور پر کام آئے۔ ان میں خطرہ کم تھا، لیکن انہوں نے وہ حقیقی خامیاں ظاہر کیں جو میں صرف الگ تھلگ سورس کوڈ کو دیکھ کر نہیں پکڑ سکتا تھا۔
اصل امتحان: Web Weavers World میں پروڈکشن
ذاتی پروجیکٹس تجربہ گاہیں (sandboxes) ہوتے ہیں۔ ان میں ڈیڈ لائنز، اسٹیک ہولڈرز، یا ایسا پرانا (legacy) CSS نہیں ہوتا جو آپ کے پیکیج سے پہلے سے موجود ہو۔ اصل امتحان تب آیا جب میں نے DTK کو اپنی کاروباری سائٹ، Web Weavers World میں شامل کیا۔ یہ ایک لائیو پراپرٹی تھی جس میں موجودہ اسٹائلز، کلائنٹ کی توقعات اور اینالیٹکس (analytics) کا خیال رکھنا ضروری تھا۔ اگر پیکیج سے کچھ خراب ہو جاتا، تو میں محض ریپوزٹری (repo) ڈیلیٹ کر کے دوبارہ شروع نہیں کر سکتا تھا۔
میں نے DTK کو بلڈ پائپ لائن (build pipeline) میں شامل کیا، اسے ایک نئی کلر کنفیگریشن کی طرف موڑ دیا، اور اسے CSS ویری ایبلز کا ایک نیا سیٹ تیار کرنے دیا۔ اس انٹیگریشن میں صرف ایک دوپہر لگی، ایک ہفتہ نہیں۔ یہی اصل اشارہ تھا۔ پہلے، ایک نیا تھیم شامل کرنے کا مطلب تھا نیا CSS لکھنا، بیس فائلز میں ہارڈ کوڈڈ (hardcoded) ہیکس ویلیوز (hex values) کو تلاش کرنا، اور یہ امید کرنا کہ میں کوئی ایج کیس (edge case) نہ بھول جاؤں۔ اب میں کنفیگریشن فائل میں ایک پیلیٹ (palette) شامل کرتا ہوں، DTK ویری ایبلز تیار کرتا ہے، اور سائٹ کا باقی حصہ انہیں استعمال کر لیتا ہے۔ تھیم کا لاجک ایک نازک دستی عمل سے بدل کر ایسی چیز بن گیا جس پر میں اتنا بھروسہ کرتا ہوں کہ اسے ساتھیوں (collaborators) کے حوالے کر سکوں۔
تین سوالات جنہوں نے میرے کام کرنے کا طریقہ بدل دیا
اس عمل سے گزرتے ہوئے میں نے ایک ذہنی چیک لسٹ (mental checklist) کو باقاعدہ شکل دینے پر مجبور ہو کر بنایا، جسے میں اب کسی بھی چیز کو ایبسٹریکٹ (abstract) کرنے سے پہلے استعمال کرتا ہوں:
- کیا یہ ویری ایبل واقعی جنرل (generic) ہے؟ اگر نام یا لاجک اصل پروجیکٹ کے کسی ڈومین تصور (domain concept) کا حوالہ دیتی ہے، تو اسے وہیں چھوڑ دینا چاہیے۔
- کیا یہ پیکیج کا حصہ ہے یا ایپلی کیشن کا؟ بزنس رولز، برانڈ کی شناخت، اور لے آؤٹ کے مفروضے ایپ میں ہوتے ہیں۔ وہ بنیادی ڈھانچہ (plumbing) جو معیاری آؤٹ پٹ تیار کرتا ہے، پیکیج میں ہوتا ہے۔
- کیا میں ایک قابلِ استعمال (reusable) مسئلہ حل کر رہا ہوں یا کسی خاص پروجیکٹ کا؟ اس کا ایمانداری سے جواب دینا سب سے مشکل ہے۔ ہم یہ سوچنا پسند کرتے ہیں کہ ہمارے حل عالمگیر (universal) ہیں، جبکہ عام طور پر وہ مقامی (local) ہوتے ہیں۔
ان سوالات کے جوابات نے مجھے اپنے ڈیزائن کو سادہ بنانے پر مجبور کیا، جو اکثر کوڈ شامل کرنے کے بجائے اسے ہٹانے سے ممکن ہوا۔ DTK نے مجھے سکھایا کہ ری یوز (reuse) کوئی ایسا تحفہ نہیں ہے جو آپ خود کو دیتے ہیں۔ یہ ایک نظم و ضبط ہے جسے آپ آسانی کو مسترد کر کے اپناتے ہیں۔
ری فیکٹرنگ (Refactoring) کے بارے میں سوچنے کا ایک مختلف انداز
میں پہلے ری فیکٹرز کو اس بنیاد پر ماپتا تھا کہ انہوں نے کوڈ کو کتنا مختصر کر دیا ہے۔ کم لائنیں ترقی محسوس ہوتی تھیں۔ اب میں انہیں اس بنیاد پر ماپتا ہوں کہ وہ کتنے نئے راستے کھولتے ہیں۔ Dynamic Theme Kit اس لیے پروقار نہیں ہے کہ یہ مختصر ہے۔ یہ اس لیے مفید ہے کیونکہ یہ اپنے اندرونی ڈھانچے کو تبدیل کیے بغیر تین غیر متعلقہ ذاتی پروجیکٹس اور ایک پروڈکشن بزنس سائٹ پر کامیاب رہا۔
یہی وہ پیمانہ ہے جو اہمیت رکھتا ہے۔ وہ کوڈ جو صرف ایک بار کام کرے، ایک خرچہ ہے۔ وہ کوڈ جو بار بار کام کرے، ایک اثاثہ ہے۔ اب میں کوئی بھی فیچر شروع کرنے سے پہلے رک جاتا ہوں۔ میں خود سے پوچھتا ہوں کہ کیا میں کچھ ایسا بنا رہا ہوں جس کی مجھے دوبارہ ضرورت پڑے گی۔ اگر جواب ہاں ہے، تو میں پہلی لائن سے ہی اسے مختلف طریقے سے بناتا ہوں۔ میں ان پٹس (inputs) کو الگ کرتا ہوں۔ میں آؤٹ پٹس (outputs) کا تعین کرتا ہوں۔ میں مفروضوں کو ختم کر دیتا ہوں۔
بہترین ری فیکٹر آپ کے کوڈ کو مختصر نہیں کرتا، بلکہ یہ آپ کے کوڈ کو ایسی جگہوں پر کام کرنے کے قابل بناتا ہے جن کا آپ نے ابھی تک تصور بھی نہیں کیا ہوگا۔
