برنامه نویسی استراتژیک و تاکتیکی

یکی از مسائل مهمی که در برنامه نویسی می توان مطرح کرد، طرز فکر (mindset) برنامه نویس، در هنگام انجام یک کار است. خیلی از سازمان ها، افراد را تشویق می کنند که کارها را با طرز فکر تاکتیکی پیش ببرند، یعنی با بیشترین سرعت ممکن، پیاده سازی ها را انجام دهند و کار را تحویل دهند. اما طرز فکری دیگری هم وجود دارد و آن طرز فکر استراتژیک است که نیازمند صرف زمان، برای طراحیِ تمیز و فکر شده است.استراتژی و تاکتیک، کلمه هایی هستند که زیاد شنیده می شوند و گاهی به جای هم استفاده می شوند. هر چند این دو کلمه، ابتدا از اصطلاحات نظامی گرفته شده اند، ولی امروزه در بسیاری از زمینه های زندگی کاربرد دارند.حدود 2500 سال پیش، سان تزو در کتاب "هنر جنگ" گفت:استراتژی بدون تاکتیک، کند‌ترین راه رسیدن به پیروزی است.تاکتیک بدون استراتژی، سر و صدای قبل از شکست است.این دو مفهوم را می توان به این صورت تعریف کرد:استراتژی، اهداف بلند مدت و نحوه برنامه ریزی برای رسیدن به آن اهداف را مشخص می کند.تاکتیک، گام های کوچک و اقدام های مشخصی است که برای رسیدن به آن اهداف انجام می دهیم.استراتژی مفهومی بلند مدت و کلان است. تاکتیک، کوتاه مدت است و تاثیر کوچک تر و مشخص تری دارد.تغییر استراتژی مانند تغییر مسیر یک ناو هواپیمابر است، قابل انجام است ولی نه به سرعت. در مقابل، تغییر تاکتیک می تواند به سرعت انجام شود.برنامه نویسی تاکتیکیاگر شما با رویکرد تاکتیکی برنامه نویسی می کنید، همه ی تمرکزتان روی تمام کردن کار است. برای مثال این که یک خطا برطرف شود یا یک feature کار کند (در واقع فقط کار کند). شاید در نگاه اول خیلی منطقی به نظر برسد، شاید این سوال پیش بیاید که چه چیزی از نوشتن کدی که کار می کند مهم تر است؟مشکل این رویکرد این است که بسیار کوتاه نگر است. برنامه نویسی که با رویکرد تاکتیکی کد می نویسد، احتمالا می خواهد یک تسک را در سریع ترین زمان ممکن تمام کند. احتمالا از سمت مدیرش یک deadline دارد و در نتیجه هیچ دغدغه ای نسبت به آینده ی آن قطعه از کد ندارد. به این فکر نمی کند که بهترین طراحی را انتخاب کند. به کاهش پیچیدگی فکر نمی کند. به وابستگی ها دقت نمی کند. هر چیزی که بخواهد سرعت کارش را کاهش دهد حذف می کند تا آن کار مشخص را به انجام برساند.همانطور که در نوشته ی مربوط به پیچیدگی در نرم افزار توضیح داده شد، پیچیدگی در طول زمان به وجود می آید، نه بر اثر یک اشتباه، بلکه بر اثر صدها و هزاران بار، که برنامه نویس به سرعت کار می کند تا پیاده سازی یک بخش را به پایان برساند و کاملا بدون فکر این کار را انجام می دهد.به مرور زمان یک اتفاق بدتر هم می افتد. پیچیدگی هایی که ایجاده شده اند، مشکلاتی به وجود می آورند که نیاز به اصلاح دارند، ولی همه ی افراد، در حال کار کردن روی وظایف دیگری هستند که باید هرچه سریع تر به انجام برسد، پس هیچکس وقت برای refactor کردن کد ندارد. به زودی وضعیت کدهای موجود طوری می شود که برای اصلاح آن باید ماه ها وقت صرف کرد و به علت نبود نیرو، هیچ اصلاحی صورت نمی گیرد. به همین دلیل وقتی یک بار برنامه نویسیِ تاکتیکی شروع شد، متوقف کردن آن کار ساده ای نیست.هر شرکتی که در زمینه ی توسعه نرم افزار مشغول است، حداقل یک برنامه نویس تاکتیکی حرفه ای دارد که کارها را سریع تر از هر موجود زنده ی دیگر در آن شرکت به انجام می رساند. در بعضی سازمان ها، با این افراد به عنوان یک قهرمان برخورد می شود و همه باید از آن ها یاد بگیرند!ولی این قهرمان ها، معمولا پشت سر خودشان یک ویرانی عظیم بر جا می گذارند. کسانی که بعد از آن ها، روی این ویرانی کار می کنند، معمولا آن ها را قهرمان نمی دانند. آن ها باید هم این هرج و مرج بزرگ را اصلاح کنند و هم به مدیران جواب بدهند که چرا سرعتشان به خوبی برنامه نویس قبلی نیست.برنامه نویسی استراتژیکاولین قدم در راه تبدیل شدن به یک برنامه نویس خوب، این است که بفهمیم کار کردن کد کافی نیست. این که مقدار زیادی ابهام و وابستگی به کد تحمیل کنیم، فقط برای این که یک پیاده سازی را به انجام برسانیم، به هیچ وجه قابل قبول نیست. مهم ترین مساله، ساختار نرم افزار در بلند مدت است.برای مثال، احتمالا بسیاری از تغییرات در آینده، شامل extend شدنِ قابلیت های فعلی نرم افزار است. پس یک برنامه نویس، باید در طراحیِ اکنون، به این مساله فکر کند که در آینده شاید این ویژگی بخواهد گسترش یابد. پس طوری آن را طراحی می کند که برای extend شدنش، نیاز به تغییرات گسترده در سیستم نباشد. در واقع باید تسهیلِ extend های آینده را به عنوان یکی از اصلی ترین وظایف خود بداند.یک برنامه نویس، نباید هدف خود را "کار کردن کد" یا "تمام کردن تسک" بگذارد، بلکه هدف اصلی او باید تولید یک طراحیِ عالی باشد که در نهایت "کار هم می کند". این طرز فکرِ استراتژیک است.برنامه نویسیِ استراتژیک، یک مدل ذهنی "سرمایه گذاری" نیاز دارد. به جای این که سریع ترین راه تمام کردن پروژه را انتخاب کنیم، زمان را "سرمایه گذاری" می کنیم تا بهترین طراحی را انتخاب کنیم. در کوتاه مدت قطعا سرعت کاهش خواهد یافت ولی در دراز مدت، کار بسیار سریع تر پیش خواهد رفت.این سرمایه گذاری به دو صورت می تواند باشد:سرمایه گذاری فعالفرض کنید یک ویژگی جدید قرار است به سیستم اضافه شود. به جای این که اولین ایده ی طراحی که به ذهنمان می رسد را پیاده سازی کنیم، کمی وقت سرمایه گذاری می کنیم و تعدادی طراحی دیگر پیدا کرده و از بین آن ها بهترین را انتخاب می کنیم. به آینده ی سیستم فکر می کنیم و نکات مهم را در نظر می گیریم. شاید کمی وقت هم برای مستندسازی سرمایه گذاری کنیم.سرمایه گذاری واکنشیهرچقدر هم که در زمان پیاده سازی یک ویژگی جدید، سعی کنیم بهترین طراحی را انتخاب کنیم، باز هم احتمالا جایی در میانه ی راه مجبور به تغییر تصمیمات گذشته می شویم، چرا که بعضی اشتباهات، فقط با گذشت زمان خود را نشان می دهند. مهم ترین مساله این که است که این اعمال این تغییرات را به تاخیر نیندازیم. کمی وقت سرمایه گذاری کنیم و آن را اصلاح کنیم. در طول زمان، این بهبود های کوچک باعث بهتر شدن سیستم می شوند. آیا با روش تاکتیکی نمی توان موفق شد؟معمولا در startup ها، روی روش تاکتیکی بسیار تاکید می شود. در این شرکت ها، تمرکز روی تمام کردن پروژه است و به این فکر می کنند که اگر پروژه به درامدزایی برسد، برای تمیزکاری وقت خواهند داشت. نکته ای که باید به آن توجه کرد این است که اگر کد تبدیل به اسپاگتی شود، اصلاح آن تقریبا غیر ممکن است. احتمالا هزینه های نگهداری نرم افزار بسیار بالا خواهد بود و توسعه ی بخش های بعدی بسیار کند پیش خواهد رفت.کدِ اسپاگتی (Spaghetti Code) یک عبارت منفی است که برای توصیف کدِ بدون ساختار و غیر قابل نگهداری، استفاده می شود. در واقع این یک ضد الگو (AntiPattern) است که از ابتدای تاریخ برنامه نویسی وجود داشته است.اصولا کدهایی که به زبان های غیر شی گرا نوشته می شود، بیشتر مستعد اسپاگتی شدن هستند، با این حال این مساله بین برنامه نویس هایی که به زبان های شی گرا کد می نویسند، ولی بر مفاهیم شی گرایی تسلط ندارند هم رایج است.کد اسپاگتی، آنقدر ساختار ضعیف و غیرواضحی دارد که حتی برنامه نویس هایی که قبلا روی این کد کار کرده اند، اگر مدت زمان کمی از آن دور باشند، برای تسلطِ دوباره روی آن، باید زمان زیادی صرف کنند.یک نکته ی مهم دیگر این است که، موفقیت یک شرکت بستگی زیادی به کیفیت کار مهندسین آن شرکت دارد. بهترین راهِ کم کردن هزینه های توسعه ی نرم افزار، استفاده از برنامه نویس های حرفه ای است و مساله این است که برنامه نویس های حرفه ای، به طراحی خوب اهمیت می دهند. اگر نرم افزار کد کثیفی داشته باشد، استخدام و کار طولانی مدت با برنامه نویس های ماهر ممکن نیست. در نتیجه شرکت باید به برنامه نویس های معمولی رضایت دهد و در درازمدت هزینه ی آن را بپردازد.به عنوان نمونه می توان به فیسبوک اشاره کرد. تا زمان زیادی، شعار شرکت این بود:"Move fast and break things"برنامه نویس های تازه نفس، که از دانشگاه فارغ التحصیل شده بودند سریع کارها را به دست می گرفتند و در همان هفته ی اول ورودشان، تغییرات را روی نسخه ی عملیاتی commit می کردند. نتیجه ی مثبت این امر آن بود که، فیسبوک به عنوان شرکتی که کارمندهایش را قدرتمند می سازد مطرح شد. آزادی عمل بسیار بود و قوانین و محدودیت های کمی وجود داشت. در نتیجه فیسبوک به عنوان یک شرکت، خوب عمل کرد، ولی روش تاکتیکی که در پیش گرفته بود، به code base آسیب زد. قسمت های بسیاری از کد، بی ثبات و غیر قابل فهم و بدون تست بود و کار کردن روی آن دشوار بود. پس از مدتی، شرکت شعارش را تغییر داد:"Move fast with solid (stable) infrastructure"با این شعار، برنامه نویس ها را تشویق به سرمایه گذاریِ زمان برای طراحی بهتر کرد.شرکت های دیگری مثل گوگل و VMware، که رویکرد استراتژیک داشتند، تقریبا همزمان با فیسبوک رشد کردند. هر دوی این شرکت ها، تاکید زیادی روی کیفیت کد و طراحی خوب داشتند و محصولاتی با قابلیت اطمینان بالا تولید کردند که پاسخگوی نیازهای پیچیده است. فرهنگ استراتژیک این شرکت ها در Silicon Valley به خوبی شناخته شده است و تعداد کمی شرکت می توانند در زمینه ی استخدام افراد فنیِ ماهر، با آن ها رقابت کنند.این مثال ها نشان می دهد که یک شرکت با هر دو رویکرد (استراتژیک و تاکتیکی) می تواند موفق شود. با این حال، قطعا کار کردن در شرکتی که به طراحی نرم افزار اهمیت می دهد و code base تمیزتری دارد، جذاب تر خواهد بود.خلاصهطراحی خوب، راحت به دست نمی آید. برای یک طراحی خوب، باید به طور پیوسته سرمایه گذاری کنیم تا مشکلات کوچک، تبدیل به فاجعه های بزرگ نشوند. باید به رویکرد استراتژیک بها دهیم و سرمایه گذاری خود را از امروز شروع کنیم نه فردا. اگر مشکلاتی که امروز در کد می بینیم را اصلاح نکنیم، این ها روی هم انباشته می شوند و احتمالا فردا اصلاحشان دشوارتر است، پس این اهمال کاری تا پایان پروژه ادامه خواهد یافت.بهتر است هر روز 10 تا 20 درصد از زمان خود را برای یک طراحی بهتر سرمایه گذاری کنیم. با این که اتمام کارها و پروژه ها به همین میزان طولانی تر می شود، ولی در بلند مدت قطعا سرعت توسعه ی نرم افزار بیشتر می شود. باید یاد بگیریم بلندمدت فکر کنیم.منبعA philosophy of software design