انواع طراحی در نرم‌افزار

بعضی وقت‌ها مفاهیمی راجع به نرم‌افزار و نرم‌افزار نویسی در ذهنم خطور می‌کند که بیان کردن آنها برای دیگران خیلی سخت است. چون اسمی برای آنها سراغ ندارم. گاهی اوقات تنها با مثال زدن و مقایسه کردن آن با مفاهیم موجود در دیگر حوزه‌ها مثل ساختمان‌سازی، خودرو یا علوم پزشکی می‌توانم منظورم را بیان کنم.

یکی از این مفاهیم تفاوت دو مدل طراحی نرم‌افزار است که به نظر شخصی من تفکیک این دو طراحی کمک زیادی به تیم‌های تولید نرم‌افزار می‌کند تا بتوانند نرم‌افزار بهتری تولید کنند. از دید من طراحی نرم‌افزار به ترتیب زمان اجرا به دو نوع تقسیم می‌شود.

طراحی کارکرد (نوع اول)

طراحی کارکرد برنامه از دید کاربرد. این نوع طراحی مواردی مثل زیر را مشخص می‌کند:
۱- روال انجام یک کار معین چطور است و شامل چرا مراحلی می‌شود.
۲- روش ارتباط کاربر با برنامه از چه طریق بیشتر باشد، صفحه کلید، ماوس یا چیز دیگر؟
۳- اگر برنامه در جایی دچار خطا شد این خطا را چطور به کاربر اعلام کند و بعد از اعلام خطا چه چیزی باید اتفاق بیفتد؟
۴- برنامه چطور باید جلوی اشتباهات احتمالی کاربر را بگیرد.
۵- کار کردن با برنامه چقدر برای کاربر راحت است؟
۶- رنگ، اندازه قلم و کوچک بزرگی دکمه‌ها و فرم‌ها چطور باید باشد؟
۷- اگر کاربر اطلاعاتی را در صفحه‌ای وارد کرد و سهواً خارج شد، آیا برنامه تمهیدات لازم را برای جلوگیری از دست رفتن اطلاعات کابر دارد؟
۸- اگر یک چیز کوچک از نیازمندی‌های برنامه دچار مشکل شد، مثلاً اینترنت قطع شد یا کاغذ پرینتر تمام شد، آیا کل برنامه از کار می‌افتد؟
۹- آیا امکان تست برنامه یا قسمتی از آن بدون تاثیر بد روی اطلاعات عملیاتی وجود دارد؟
۱۰- امکانات backup/restore چقدر آسان و مطمئن است؟
۱۱- آیا سابقه‌ای از خطاهای سیستم وجود دارد؟
۱۲- آیا ساختار برنامه با منطق و صنعت مشتری (حسابداری، انبارداری و…) منطبق است؟
۱۳- آیا می‌توان در سیستم مشخص کرد که هر کسی چه کاری کرده؟
۱۴- آیا واقعاً برنامه توانسته سرعت عمل کاربرانش را بالا ببرد؟
۱۵- آیا برنامه می‌تواند علت خطاهای به وجود آمده را خوب بفهمد و علت واقعی خطا را نمایش دهد؟
۱۶- آیا برنامه طوری نوشته شده که نیاز به حضور مستمر افراد تیم پشتیبانی نداشته باشد؟
۱۷- چقدر طول می‌کشد تا کاربر بتواند به اطلاعات مورد نظرش دست پیدا کند؟ به عبارت دیگر جستجوی اطلاعات چقدر آسان یا سخت است.
۱۸- آیا برنامه یادش می‌ماند که کاربر در مراحل قبلی در حال انجام چه کاری بوده؟ این موضوع به کاربر کمک می‌کند تا مجبور نشود یک سری عملیات را مجدداً تکرار کند. مثلاً وقتی روی یکی از اقلام Grid کلیک شد و وارد صفحات اطلاعات جزیی شد، بعد از اتمام کار در صفحه جزیی بتواند به همان صفحه و آیتم از Grid قبلی بازگردد. یا اگر مثلاً کاربر در سه روز پیش در حال وارد کردن اطلاعات حضور و غیاب بود، بعد از سه روز باز هم بتواند از همانجا کارش را ادامه دهد.
۱۹- آیا امکان کار به صورت تعداد بالا یا فله‌ای (Bulk) موجود است؟ مثلاً اگر قرار شد ۱۲۰ تا نامه در پوشه «اداره مالیات» بایگانی شود باید این کار را تک تک انجام داد یا امکان انجام دفعتی آن موجود است؟
۲۰- آیا چیزی به نام امکان «ذخیره موقت» موجود است؟ مثلاً اگر انجام کاری ۳۰ دقیقه طول بکشد، آیا کاربر می‌تواند وسط کار بلند شده و با ذخیره موقت کار خیالش راحت باشد که اگر حتی کامپیوترش خاموش هم که شد باز کار نصفه نیمه‌اش از دست نخواهد رفت؟
۲۱- آیا برنامه امکان یادگیری از کاربر را دارد؟ مثلاً برنامه می‌تواند از کاربر یاد بگیرد روش اسکن و ذخیره مدارک چطور است و خودش این کار را با کمک چیزی مثل macro به طور خودکار و با کمترین دخالت کاربر انجام دهد؟
۲۲- آیا با یک نگاه کلی به برنامه می‌توان وضعیت فعلی برنامه مثل ارتباط با شبکه، عدم hang یا کاربر login کرده را فهمید؟
۲۳- …

بیشتر موارد این صفحه را می‌توان با اصطلاحاتی مثل کاربر پسندی (UserFriendly)، کاربرد پذیری و خطا ناپذیر سازی
بیان کرد. اما با این وجود منظور من از طراحی نوع اول همه‌ی این موارد با هم است. به نظر من انجام این طراحی توسط هر شخصی که نسبت به نرم‌افزار، کامپیوتر و نیازهای کاربران آشنایی و تجربه کافی دارد قابل انجام است و هیچ لزومی به برنامه‌نویس بودنش نیست. البته این به معنی کم اهمیت بودن موضوع نیست. بلکه برعکس خیلی مهم است. کافی است نگاهی به طراحی(نوع اول) ویندوز، Office، جیمیل، Visual Studio یا ویکی‌پدیا بیندازید تا بفهمید رعایت همین موارد ساده چقدر در موفقیت آنها تاثیر داشته.

طراحی فنی (نوع دوم)

این نوع طراحی را خیلی راحت‌تر می‌توان درک کرد. منظور از این طراحی، طراحی مورد نیاز برای پیاده‌سازی نرم‌افزار از جمله موارد زیر است:
۱- معماری لایه‌های نرم‌افزار چطور باشد؟
۲- از کدام رابط برای ارتباط با دیتابیس استفاده شود؟ از ADO.NET یا NHibernate؟
۳- تعریف عملیات در یک کلاس واحد باشد یا در طول چند کلاس پراکنده؟
۴- آیا لازم است از interfaceها استفاده شود؟
۵- تبادل اطلاعات بین صفحات از طریق query string انجام شود یا session؟
۶- دریافت اطلاعات از متودها به صورت ref و out باشد یا از کلاس‌های کمکی موسوم به DTO استفاده شود؟
۷- خوانایی مهم‌تر است یا performance؟
۸- منطق تجاری برنامه در اسکریپت‌ها و stored procedureهای دیتابیسی نگهداری شود یا در کلاس‌های سرویسی دات‌نت؟
۹- استفاده از تریگرها در دیتابیس مجاز است یا خیر؟
۱۰- از کدام فناوری برای Ajax استفاده شود؟
۱۱- …

همین طور که مشخص است این نوع طراحی فقط مخصوص برنامه‌نویس‌هاست. شاید بتوان گفت بخش زیادی از موضوع این نوع طراحی مربوط است به مبحث software artichecture. مشخص است که اگر بخواهیم در طراحی کارکرد (نوع اول) دستمان باز باشد باید حسابی به طراحی فنی (نوع دوم) مسلط بوده و آن را به بهترین وجه ممکن انجام داده باشیم.

مقایسه با صنعت ساختمان

اگر شما هم مثل من در دوران دانشگاه افتخار هم صحبتی با چندین دانشجوی معماری و عمران را داشته باشید، به درستی حدس خواهید زد که طراحی کارکرد (نوع اول) بسیار شبیه به کار معمارها و طراحی فنی (نوع دوم) بسیار شبیه به کار مهندسین عمران است. به عبارت دیگر تفاوت این دو نوع طراحی کاملاً مشابه تفاوت رشته‌های معماری و عمران می‌باشد. کار معمارها طراحی فضاها، نورپردازی، رنگ، بافت، دوری و نزدیکی اتاق‌ها به هم، مکان صحیح مثلاً آشپزخانه یا اتاق خواب والدین در ساختمان و… با توجه به مسائل فرهنگی، سبک‌های هنری، مسائل اجتماعی و حتی مذهبی و دیگر موارد است. در حالی که کار مهندسین عمران پیاده‌سازی طرح‌های معمارها و محاسبات فنی و ریاضی آن است. مهندسین عمران باید حساب کنند چه تیرآهنی با چه ضخامتی مورد نیاز است، عمق پی ساختمان چقدر باید باشد، ضخامت دیوارها مختلف چقدر باید باشد، از چه نوع سیمان، ماسه یا آجری باید استفاده شود و…

بی‌توجهی به گزارشات سیستم

یکی از مراحل تولید هر سیستمی بخش گزارشات آن است. با این که در بیشتر سیستم‌ها خصوصاً سیستم‌های مالی و اداری و امثال آنها که پر از Businness هستند، درک و پیاده‌سازی گزارشات بخش مهمی از سیستم را تشکیل می‌دهد، ولی متاسفانه اهمیت کافی به آنها داده نمی‌شود.

معمولاً در تحلیل و طراحی سیستم چندان توجهی به گزارشات نشده و پیاده‌سازی آن تا آخرین روزهای فاز توسعه عقب انداخته می‌شود. در چنین روزهایی هم افراد اصلی تحلیل و طراحی چندان در دسترس نیستند، دیگر افراد تیم تا اندازه‌ای منطق پشت گزارشات را به فراموشی سپرده‌اند و حتی نمایندگان مشتری هم عوض شده یا دیگر وقت کافی برای پاسخگویی به سوالات مجری را ندارند. علاوه بر این‌ها اگر برای پیاده‌سازی گزارشات نیاز به دستکاری مختصری در ساختار برنامه یا جداول آن باشد انجام آن کمی سخت می‌شود چون ساختار برنامه در مراحل قبلی نهایی شده و به تایید رسیده. در بعضی شرکت‌ها هم پیاده‌سازی گزارشات به طور کامل به افرادی سپرده می‌شود که تخصص آنها صرفاً کار با ابزارهای گزارش‌ساز مثل SQL Server Reporting Services است و چندان از Businness سیستم خبر ندارند.

گاهی اوقات با خودم فکر می‌کنم واقعاً چرا باید همچین داستان‌هایی به وجود آمده و کیفیت کار را پایین بیاورد. در حالی که می‌شود در همان مراحل طراحی سیستم، queryها، scriptها یا سرویس‌های مربوط به گزارشات را آماده و تست کرده و در مراحل پایانی فقط گزارشات را به آنها وصل کرد.

استفاده از مفاهیم جدید تولید نرم‌افزار

روند طراحی و توسعه نرم‌افزار طی ده سال گذشته حتی در همین ایران خودمان هم تغییرات زیادی داشته. آن زمان یعنی حدود سال ۷۹ شمسی مردم تازه از شر FoxPro خلاص شده و به دیتابیس‌های مدرن‌تری مثل Access، MS SQL Server و Oracle رو آورده بودند. برنامه‌نویسی در عصر ویندوز راحت‌تر و منظم‌تر شده بود. تا قبل از آن عموماً کسی لذت Foreign Key و Delete/Update Cascade را کشف نکرده بود. طی این ده سال استفاده از Database Driver و ADO رواج زیادی پیدا کرد. در این دوره آنها که منظم‌تر بودند از نمودارهای ERD برای بیان ساختار دیتابیس، نرمال‌سازی، کلاس‌های مجزا برای دسترسی به دیتابیس (معماری سه لایه) و… استفاده می‌کردند.

اما اکنون آن دوران به سر آمده و ما خیلی وقت است که وارده دوران Domain Driven Design یا همان DDD شده‌ایم. در عصر DDD هیچکس مستقیماً به دیتابیس وصل نمی‌شود بلکه از ORM‌ استفاده می‌کند. روابط بین entityها به جای ERD با UML Class Diagram تعریف می‌شود و معماری‌های چندلایه‌ای با استفاده از DDD خیلی راحت‌تر شده و…

حال سوال این است که آیا لازم است ما هم صرفاً به خاطر همراهی با زمان یه سمت Domain Driven Design و Object Oriented برویم یا این که واقعاً نفعی برای ما و شرکت‌مان در آن وجود دارد؟ جواب این سوال هر دو است. چون اولاً وقتی که همه دنیا به این سبک جدید رو آورده‌اند خیلی سخت است که ما همان روش‌ها و ابزارهای قدیمی را نگه داریم و خلاف جریان آب شنا کنیم. ثانیاً عصر جدید امکانات بسیار خوبی را با خود به همراه آورده است و نباید آن را به این سادگی از دست بدهیم.

عصر جدید یعنی دنیای Domain Driven Design و Object Oriented که با استفاده از ORMها و UML محقق می‌شود به شما کمک می‌کند که:
‫۱- کد شما قابلیت نگهداری بالایی داشته باشد.
‫۲- پیدا کردن و برطرف کردن باگ‌ها راحت‌تر باشد.
‫۳- اگر طراحی درست انجام شده باشد، برنامه‌نویسی راحت‌تر خواهد بود.
‫۴- مزایای معرفی شده در Object Oriented به طور ملموسی در دسترس قرار خواهد گرفت. مفاهیمی مثل Inheritance باعث می‌شود حجم کد کاهش یابد.
‫۵- کدهای DDD خیلی منظم‌تر از کدهای تولید شده در دوران قبل هستند.
‫۶- تولید نرم‌افزارهای DDD هم‌خوانی بسیار بیشتری با متودولوژی‌های جدید اسکرام، XP و… دارد.
‫۷- …

در بین شرکت‌ها و تیم‌های نرم‌افزاری ایرانی تعداد قابل توجهی به روش‌های عصر جدید رو آورده‌اند. یعنی از ORM استفاده می‌کنند، کل کار را به صورت Object Oriented جلو می‌برند، Documentation آنها بر اساس UML است و … اما متاسفانه هنوز خیلی‌ها هستند که خود را از لذت و کارایی عصر جدید محروم کرده‌اند. به نظر من تنها عاملی که باعث می‌شود این طور افراد همچنان به استفاده از روش‌های قدیمی ادامه دهند عدم آگاهی نسبت به روش‌های جدید است. چون هیچ مدیر پروژه یا رییس شرکتی دوست ندارد کاری را که می‌شود در شش ماه انجام داد در هشت ماه انجام دهد و نهایتاً هم کدی را تحویل بگیرد که نگهداری و توسعه آن خیلی هم سخت باشد. به همین خاطر به این طور افراد توصیه می‌گردد اگر هم از روش‌های قدیمی خیلی هم راضی هستند اقلاً مطالعه‌ای در مورد روش‌های جدید و مزایای آن داشته باشند.