آیا کپی/پیست واقعا بد است؟
برنامهنویسی با استفاده از کپی/پیست یعنی یک کپی از کد موجود در پروژه را برداشته و با هدف دیگری مورد استفاده قرار دهیم. در مذمت چنین حرکتی بارها شنیدهایم اما آیا واقعا برنامهنویسی با استفاده از کپی/پیست همواره بد است؟
برنامهنویسی با استفاده از کپی/پیست تعدادی از اصول برنامهنویسی مثل DRY (Don’t Repeat Yourself) را نقض میکند.یک پاد الگوست که هزینه زنده بودن کد برای مدت طولانی را زیاد میکند.
اما یکی از راههای طبیعی برای انجام شدن کارهاست، پیدا کردن چیزی که قبلا کار میکرده است، چیزی که شباهت زیادی به آن چیزی که مدنظر شماست دارد، یک کپی از آن را در نظر گرفته و به عنوان نقطه شروع استفاده کنید. تقریبا همه برنامهنویسان در برههای از زمان چنین کارهایی کرده اند. این به این دلیل است که زمانهایی هست که کپی/پیست نه تنها راحت است بلکه ممکن است کار درستی هم باشد.
ابتدا اجازه دقیق کپی/پیست را دقیقتر روشن کنیم. کپی/پیست به معنی کپی کردن مثالها از اینترنت نیست، که این کار هم میتواند مزایا و معایب خود را داشته باشد. منظورمان از کپی/پیست وقتی است که برنامهنویسان با استفاده مجدد از یک کد، در شرایطی که مساله شبیه مسالهای دیگر در سیستم باشد، میخواهند راه کوتاهتری بیابند. در این شرایط یک کپی از مساله مشابه را به عنوان پایه در نظر گرفته و سعی میکنند آن را تغییر دهند.
در ابتدای مراحل طراحی و توسعه، کپی/پیست هیچ مزیتی نخواهد داشت. کد و طراحی هنوز تغییرپذیر هستند، این شانس شماست که به یک مجموعه صحیحی از مدلها، توابع و کتابخانهها بیندیشید تا کاری را بکنید که سیستم نیاز دارد و چیز زیادی برای کپی کردن وجود ندارد. در انتهای مراحل توسعه، وقتی که کد زیادی نوشته شده و به خصوص زمانی که سیستم بزرگ با عمری طولانی تولید میکنید که نقش کپی/پیست روشنتر خواهد شد.
چرا کپی/پیست؟
برنامهنویسان برای صرفهجویی در زمان کپی/پیست میکنند. از ابتدا نقطه شروعی وجود دارد که شما مطمئن هستید کار میکند. تمام کاری که لازم است انجام گیرد این است که چه چیزی لازم است تغییر کند یا اضافه شود. شما میتوانید روی مشکلی که میخواهید حل کنید تمرکز کنید، روی چیزی که متفاوت است و در این حالت لازم است تنها بفهمید از چه چیزی دقیقا میخواهید استفاده کنید. شما خیلی آزادانه تر میتوانید روی کد حرکت کرده و تغییرات لازم را در آن اعمال فرمایید، میتوانید کد را تمیز کنید یا بخشهای زاید را حذف کنید. تمام این مراحل مهم هستند چرا که تا وقتی مساله را عمیقا نفهمیده باشید ممکن است ندانید چه چیزی را لازم است نگهدارید، چه بخشی را تغییر دهید و چه چیزی را اصلا نیاز ندارید.
برنامهنویسی با استفاده از کپی/پیست ریسک را هم کاهش میدهد. اگر شما به عقب برگردید و کد موجود را تغییر و گسترش دهید تا کاری که امروز میخواهید را هم انجام دهد، ریسک خراب کردن چیزی که قبلا کار میکرده است وجود دارد اما اگر یک کپی از آن بگیرید و روی آن کار کنید ایمنتر و کم هزینهتر خواهد بود.
یافتن طراحی مشترک، مدل صحیح و تفاوتها برای پشتیبانی از پیادهسازیهای مختلف و مدیریت خطاها میتواند سخت و زمانبر باشد. شما ممکن است با کدی را درنهایت تحویل دهید که درک و مراقبت و نگهداری آن در آینده سختتر است. در هر صورت مساله این است که در طراحی اولیه خطاها و گسترشهای متفاوت پیشبینی نشده و بازآرایی تنها میتواند اندکی بهبود ایجاد کند. شما ممکن است به طراحی و پیادهسازی جدیدی نیاز داشته باشید.
تغییر کد موجود، بازآرایی یا نوشتن مجدد بخشهایی از آن تا به یک کد همه منظوره و مشترک و قابل گسترش تبدیل شود میتواند هزینه و ریسک به همراه داشته باشد. شما نمیتوانید تنها به این دلیل که میخواهید ویژگیهای جدیدی ایجاد کنید دسترسی کاربران موجود را با مشکل روبرو سازید. باید با دقت بسیار بیشتری رفتار کرد. نه تنها باید جزییات کاری که میخواهید انجام بدهید را باید در نظر داشته باشید، بلکه باید به تمام جوانب رفتارهای سیستم موجود هم دقت کنید که آنها را هم حفظ کنید.
خیلی سادهانگارانه است که فکر کنیم همه این رفتارها در تستهای اتوماتیک شما در نظر گرفته میشوند. لازم است که دوباره به عقب برگردیم و مجددا تستهای یکپارچهسازی را انجام دهیم و این مساله خود نیاز است که مجددا هفتهها و ماهها صرف تست مجدد شود که خود کاری سخت و هزینهبر است و کاربران فعلی از علت این زمان و هزینهای که مصرف میشود آگاه نخواهند بود چرا که از دید آنها همه چیز خوب کار میکرده است.
در این شرایط کپی/پیست کردن و نگاه مجدد به آن در آینده برای بازآرایی یا حتی تغییر طراحی در صورت لزوم راه حل مناسب است.
در کتاب Making Software در فصل Copy-Paste as a Principled Engineering Tool آن، Michael Godfrey و Cory Kasper هزینه برنامهنویسی با کپی پیست را مطالعه کرده و مواردی که در آنها کپی پیست منطقی به نظر میرسد را به شکل زیر مطرح نمودند:
۱- انشعاب (Forking): ساختن هدفمند انواع مختلف برای سختافزار یا پلتفورمهای متفاوت یا برای اهداف اکتشافی
۲- ساخت نمونه (Templating): بعضی زبانها از کتابخانهها و توابع اشتراکی پشتیبانی نمیکنند پس ممکن است لازم باشد کپی/پیست به منظور به اشتراک گذاری کد صورت گیرد. جایی در شروع، اولین برنامهنویس COBOL یک برنامه نمونه برای COBOL نوشت، در ادامه برنامهنویسان از یکدیگر کپی/پیست میکردند.
۳- سفارشی سازی (Customization): ساختن راهحلهای موقت، تا وقتیکه موقت هستند.
۴- رویه مایکروسافت در “کپی کن و مالک آن شو” برای حل مشکلات در سازماندهی توسعه پروژههای بزرگ. یک تیم از گروه دیگر کد را دریافت میکرد و آن را برای هدف خود تغییر و تطابق میداد و در این زمان مالک کد میشد. این یک رویکرد عمومی در کدهای متنباز نیز به شمار میرود.
نظر شما چیست؟ آیا واقعا کپی/پیست انقدر که گفته میشود بد است؟
در مطلبی دیگر شرایطی که کپی/پیست میتواند مشکلزا باشد را معرفی خواهیم کرد.
منبع:
سلام. ممنون از پست خوبتون. به نظر من برنامه نویسان تازه کار باید همه چیز رو از پایه بنویسن. یاد اوایل دوران دانشجویی خودم افتادم که میخواستم با یک چیپ AVR اطلاعاتی رو از میکرو اس دی بخونم و بنویسم. برای این کار از کتابخونه FAT که از قبل بصورت آماده موجود بود استفاده کردم و یجورایی کار شدش هلو برو تو گلو! خیلی راحت و کم هزینه (به لحاظ زمان و انرژی). اما زیاد راحت نبودم یعنی انگار که اون کار بخصوص رو شخص دیگه ای انجام داده. این شد که خودم نشستم و درایور خودم رو نوشتم. صد البته که به اون خوبی کار نمیکرد اما نتیجه این شد که کلی چیز جدید یاد گرفتم از جمله روش ارسال دیتا از طریق پروتکل SPI که بعدها هزار جای دیگه هم بدردم خورد. البته شکی در اون نیست که نمیشه همه چیز رو از پایه نوشت. اما کسی که این کارو کرد با فاصله خیلی زیادی از دیگران پیشی گرفت. توصیه میکنم این لینک رو هم مطالعه کنین البته با شیتلر شکن:
https://www.quora.com/Why-do-so-many-beginner-programmers-think-they-should-build-everything-from-scratch