
طراحی نرم افزار، سخت است. در طراحی نرم افزار، به احتمال خیلی زیاد، اولین فکری که به ذهن می رسد، بهترین فکر نیست. اگر به جای پیاده سازیِ اولین فکر، سعی کنیم گزینه های دیگری را بررسی کنیم، و از ابعاد دیگر به مساله نگاه کنیم، قطعا به نتایج خیلی بهتر خواهیم رسید.
باید دوباره و چندباره فکر کرد!
تصور کنید می خواهیم برای مدیریت متنِ یک فایل، کلاسی طراحی کنیم، که قرار است توسط یک ویرایشگر متن استفاده شود.
اولین کار این است که واسط کلاس را طراحی کنیم (کلاس یک ماژول است، شامل واسط و پیاده سازی). نخستین فکری که ممکن است به ذهن برسد این است: یک طراحی بر اساس سطرهای متن، شامل 3 متد افزودن، ویرایش و حذف خطوط از متن. یک برنامه نویسِ معمولی، ممکن است بلافاصله، با همین ایده شروع به کدنویسی بکند.
اما یک برنامه نویس حرفه ای، این فکر اولیه را کنار گذاشته، و به طراحی جایگزین می اندیشد. طراحی جایگزین می تواند به این شکل باشد: متدهای کلاس، کاراکتر را به عنوان ورودی گرفته، آن را در خطوط مشخصی از متن اضافه می کنند یا از آن حذف می کنند.
ولی این برنامه نویس حرفه ای، به همین دو ایده اکتفا نمی کند، طراحی سوم می تواند اینگونه باشد: متدهای کلاس، در یک position مشخص (فارغ از خطوط متن)، مثلا در position شماره 14، یک تعداد کاراکتر را اضافه یا حذف می کنند.
نکته ی مهم در این طراحی ها این است که تا جای ممکن با هم تفاوت های ریشه ای داشته باشند. حتی اگر مطمئن هستید که فقط یک راه وجود دارد، سعی کنید یک طراحی دیگر پیدا کنید، هر چقدر هم که بد باشد و نامربوط به نظر برسد. با این روش هم بیشتر یاد می گیرید، هم نقطه ضعف های طراحی اولیه را پیدا می کنید.
همچنین می توان یک لیست از مزایا و معایب هر کدام از طراحی ها تهیه کرد. مثلا یکی از موارد این لیست می تواند میزان سادگی استفاده از ماژول، توسط ماژول های دیگر باشد. در مثالی که بررسی کردیم، طراحی بر اساس خطوط، زحمت زیادی را به ماژول های دیگر تحمیل می کند تا از متدهای کلاس استفاده کنند. چرا که آن ها باید بدانند متن از چه خطوطی تشکیل شده، دانش مربوط به متن های چند خطی را داشته باشند و بدانند چگونه خطی که را می خواهند ویرایش کنند شناسایی کنند. همچنین در طراحی بر اساس یک کاراکتر (طراحی دوم)، اگر استفاده کننده بخواهد چند کاراکتر را تغییر دهد، باید در یک loop، عملیات را انجام دهد.
موارد دیگری که می توان در این لیست داشت:
بعد از این که لیست مزایا و معایب را تهیه کردید، بهتر می توانید در مورد انتخاب یک طراحی تصمیم گیری کنید. ممکن است یکی از طراحی ها را انتخاب کنید، یا ویژگی های چندتا از آن ها را با هم ترکیب کنید و یک طراحی به دست بیاورید که از تک تک طراحی های قبلی بهتر باشد.
حتی ممکن است بعد از بررسی، متوجه شوید هیچ کدام از طراحی ها به اندازه ی کافی جذاب نیست. در این صورت، از مشکلات و معایب طراحی های قبلی که کشف کرده اید استفاده کنید، تا بتوانید به یک طراحی جدید برسید.
فقط در طراحی یک کلاس نیست که باید چندبار فکر کنید. مثلا وقتی واسط یک ماژول را چندبار طراحی کردید و به نتیجه رسیدید، در زمان پیاده سازی هم باید از این روش استفاده کنید. در مثالِ ویرایشگر متن، ممکن است زمان پیاده سازی، اولین فکری که به ذهن می رسد استفاده از یک linked list باشد، ولی بعد باید پیاده سازی های جایگزین پیدا کنید. مثلا array با تعداد مشخص، یا هر ساختار داده ی دیگری که می توان در آن پیاده سازی خاص استفاده کرد. بعد با روال قبلی، برای آن ها مزایا و معایب مشخص کنید و از بین آن ها بهترین را انتخاب کنید.
در انتخاب معیارهای خود دقت کنید. مثلا در پیاده سازی، ممکن است مساله ی مهم، پرفورمنس و سادگی باشد. ولی در انتخابِ واسط، معیارِ مهم، نحوه ی استفاده ی دیگران از ماژول است. اگر یک سطح بالاتر برویم، در انتخاب طراحی های معماری کلان، معیارها و وزنی که به آن ها می دهیم، به طور کلی تفاوت دارد.
دقت کنید که طراحیِ دوباره، زمان زیادی نمی گیرد. برای یک ماژول کوچک مثل یک کلاس، شاید تنها یک یا دو ساعت زمان لازم باشد، تا طراحی های جایگزین پیدا کنیم و از بین آن ها انتخاب کنیم. در مقایسه با زمان پیاده سازی، که ممکن است چند روز طول بکشد، این یکی دو ساعت اصلا مقدار زیادی نیست. در عوض، صرف کردن این دو ساعت، قطعا باعث می شود به طراحی بهتری برسیم و در بلندمدت، در زمان صرفه جویی کرده ایم. در ماژول های بزرگتر، ممکن است این دو ساعت تبدیل به چند روز شود، ولی فواید آن هم بیشتر خواهد بود چون تاثیر آن را در بخش های بیشتری از سیستم خواهیم دید.
برای برنامه نویس های باهوش، در مسیرِ رشد شغلی شان، یک خطر بالقوه وجود دارد. آن ها ممکن است در ابتدای کارشان، که با سیستم های ساده تر کار می کنند، همیشه اولین ایده را به کار ببرند و نتیجه هم بگیرند. در طول زمان، ممکن است فکر کنند که همیشه قرار است اولین ایده، بهترین ایده باشد و این طرز فکر، آسیب زننده است. وقتی فرد این عادت را در خودش پرورش دهد که همیشه با اولین ایده کار را شروع کند، در طول زمان که کار روی سیستم های پیچیده تر و بزرگ تر را در دست می گیرد، ممکن است دیگر اولین فکری که به ذهنش می رسد بهترین نباشد. در آن صورت، تغییر عادت شاید بسیار سخت باشد و کارایی فرد پایین بیاید، چرا که طراحی سیستم های نرم افزاری بزرگ، یک قانون دارد:
هیچ کس به آن اندازه باهوش نیست، که با اولین فکر به بهترین نتیجه برسد.
این که شما چندبار به یک مساله فکر کنید، به این معنی نیست که شما انسان باهوشی نیستید، بلکه به این معنی است که مساله واقعا سخت است، و کار کردن روی یک مساله ی سخت، بسیار جذاب تر از حل کردن مساله ی آسان است، که احتمالا خیلی به فکر کردن نیاز ندارد و با اولین ایده می توان به راه حل رسید.
اگر در طراحی نرم افزار، با این رویکرد پیش بروید که اولین ایده را کنار گذاشته و ایده های جایگزین پیدا کنید، نه تنها در نهایت به یک طراحی بهتر برای نرم افزار می رسید، بلکه مهارت های شما در طراحی نرم افزار بهتر خواهد شد. طی کردن این فرایند، که رویکرد ها و روش های مختلف را کشف کنید و آن ها را با هم مقایسه کنید، به شما در شناسایی فاکتورهایی که یک طراحی را خوب یا بد می سازد، کمک خواهد کرد. در طول زمان، شما قادر خواهید بود به راحتی یک طراحی بد را تشخیص دهید و آن را به یک طراحی خوب تبدیل کنید.