دسته: مهندسی نرم افزار

نگرشی نو به شی گرایی

داستان از این قراره که روزی یک نفر از دهی به شهر میاد و از قضای روزگار به یک کنسرت موسیقی میره. در بازگشت از شهر در راه به مطرب ده میرسه که داشته با پسرش ساز و دهل میزده. همین که مطرب رو می بینه بهش میگه که من توی شهر رفتم یک جایی به اسم کنسرت و کلی از همکارات رو یک جا دیدم. مطرب هم که تا به اون روز کنسرت ندیده و نشنیده بوده، با بهت می پرسه که کنسرت چیه؟

مرد دهاتی میگه که کنسرت یه جایی که اولش که رفتیم تو یه عده روی یه بلندی با سازهاشون نشسته بودند و هر کی برای خودش هی ساز میزد (حواستون که هست داشتند سازهاشون رو کوک می کردند). بعد یکی که اصلا ساز نداشت از در اومد تو و همه براش دست زدند. بعد هم روشو کرد به مطربهای روی بلندی و شروع کرد به دستور دادن که تو بزن و تو نزن، تو بزن، تو نزن و الی آخر. آخرشم به همشون گفت دیگه نزنید. بعد هم مردم براش دوباره دست زدند و اون هی دولا و راست میشد می گفت من نبودم اینا بودن من نبودم اینا بودن

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

منبع : در گذار عمر

مسابقه – نسخه بتا – آزمایش نرم افزار

فکر کنم چند ماه قبل یک ایمیل برایم رسیده بود که محتوایش برایم جالب بود. احتمالا اکثر دوستان نیر ایمیل های مشابه را دریافت کردند یا از متن آن که در پایین می خواهیم به آن اشاره کنم از طریق سایت های دیگر باخبر شده اند. ایمیل مربوط بود به یک مسابقه که توسط شرکت مایکروسافت پشتبانی و حمایت می شد و مربوط بود به ارائه یک مقاله در مورد ویژوال استودیو 2008 یا پیاده سازی یک برنامه در این محیط و تاکید مسابقه نیز بر روی ویژگیهای جدید این محیط مانند Linq و … بود. و جایزه مسابقه از نظر مالی فکر کنم مبلغ جالبی بود ولی دقیقا یادم رفته است که مبلغ جایزه نفر اول چقدر بود. فکر کنم آنزمان هنوز نسخه اصلی برنامه نیز ارائه نشده بود. همانروز ایمیل را به چند تا از دوستانم نشانم داد و گفتم که فکر می کنید هدف شرکت مایکروسافت از انجام این مسابقه چه می تواند باشد؟ (این سوال را حالا از تک تک شما دوستان نیز دارم) حتی یکی از دوستانی که کمی روی این سوال بحث کردیم یکی از طرفداران دوآتشه شرکت بورلند و محصولاتش بودند و می گفتند که حتی توی یک مسابقه مشابه که شرکت بورلند چند سال قبل روی محیط دلفی برگزار کرده بود جز منتخبان مسابقه بودند. ولی اکثر پاسخ دوستان، پاسخ های بود که به نظر من زیاد جالب نبودند چون خود شرکت مایکروسافت خودش می توانست بدون هیچ زحمتی خودش اینکارها را انجام دهد. یا بعضی از پاسخ ریشه ها در محیط و فرهنگی بود که ما در داخل کشور با آن روبرو هستیم. ولی یکی از دلایل عمده که به نظر من می تواند وجود داشته باشد موضوعی است که به عینا در کتاب کسب و کار به شیوه بیل گیتز (Business the bill gates way) به آن اشاره شده است (قسمت پایین از کتاب اشاره شده است ولی نوشته های با رنگ آبی نظرات شخصی من هستند):

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

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

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

بسیاری از شرکت های دارای تکنولوژی پیشرفته منافعی در فرآورده های آتی مایکروسافت مایکروسافت دارند چونکه نرم افزار و سیستم های که آنها تولید می کنند متکی به نرم افزار مایکروسافت است. آنها از اطلاعات پیشاپیش تیمهای ایجاد کننده شرکت و همچنین جهت و سمت و سوی حرکت فن آوری بهره برداری می کنند که این عامل می تواند تفاوت مهمی در موفقیت فرآورده های آتی خود آنها داشته باشد.”

البته دریافت بازخورد از مشتری در محصولات مایکروسافت دیگر فقط به نرم افزار بتا محدود نمی شود، اگر کمی به پیام های که در محصولات این شرکت نرم افزاری ظلاهر می شوند دقت کنیم نحوه دریافت بازخورد را خواهیم یافت مثلاً ….

منتظر نظرات شما هستم.

حق با مشتری است یا نه؟

کاربران نرم افزار واقعاً افراد مبتدی هستند، آنها هیچ اطلاعات در مورد نرم افزار ندارند، تمام اعتراضات آنها بخاطر عدم دانش و … کاربران هست و سیستم عملکرد درستی دارد. جملاتی مانند جملات بالا و حتی بدتر از آنها را بارها در محیط کار خود شنیده و یا به زبان آوردیم. ولی واقعا اینگونه است یا نه؟ ما چقدر باید به اعتراضات کاربران خود گوش دهیم؟

چند روز قبل برای رفع مشکل در سیستم نرم افزاری یکی از مشتریان به شرکت آنها رفته بودم، تقریبا اولین باری بود که بخاطر اینکار به یک شرکت مراجعه می کردم، و همین کار دلیلی برای نوشتن این مطلب شد. شرکت مورد نظر فکر کنم تقریبا همزمان با ورود من به رشته نرم افزار، از نرم افزار مورد نظر استفاده می کند یعنی چیزی نزدیگ به 5 سال. ولی چیزی که برای من جالب بود، سوالات بسیار ساده و پیش پا افتاده آنها در مورد نرم افزار بود که از من می پرسیدند. سوالاتی که فکر می کردم هر کسی بعد از چند ماه استفاده از نرم افزار باید خودش در جواب دادن به آنها استاد باشد (کاربران نرم افزار مورد نظر در طول این چند سال تغییر نکرده اند.!). گفتم حق با نرم افزاریها است که اغلب اعتراضات کاربران را نادیده می گیرند(حداقل در گروههای که من از نزدیگ آنها رادیده ام). ولی یک چیز باعث شد که فورا تغییر عقیده بدهم. یک متن که تازه توی یک EBook خوانده بودم، سعی می کنم بعد از این  همیشه با این موضوع به این صورت برخورد کنم. متنی را که گفتم در کتاب Practices of an Agile Developer خوانده بودم که در پایین عین متن را آوردم. فقط چند قسمت از این کتاب را مطالعه کردم کتاب بسیار جالبی بود، و از همه زیباتر شیوه نگارش کتاب بود، در کل کتاب از دو شخصیت استفاده شده است چیزی شبیه سوژه های کارتونی یک شخصیت مثبت (یک فرشته که شیوه صحیح را نشان می دهد) و یک شخصیت منفی که شیوه اشتباه برخورد با مسئله را نشان می دهد.(جملات قرمز توصیه شخصیت منفی است و جملات سبز توصیه شخصیت مثبت است).

Listen to Users

 

Users are always complaining. It’s not your fault; they’re just too stupid to read the stinkin’ manual. It’s not a bug; they just don’t understand. They should know better.”

Andy once worked for a large company that developed products for high-end Unix workstations. This wasn’t the sort of environment where you could just run setup.exe or pkgadd to install the software. You had to copy files and tune various settings on your workstation.

Andy and his team thought everything was going well, until one day Andy was walking past the tech support area and overheard a support engineer laughing loudly into the phone: “Oh, it’s not a bug; you made the same mistake everyone does.” And it wasn’t just this one engineer.

The whole department was chuckling at the poor, naïve, stupid customers.

Apparently there was a situation where you, the hapless customer, had to go tweak some obscure system file to contain a magic value, or otherwise the application would not run at all. No error message, no crash, just a big black screen followed by an abrupt exit. Granted, a line in the installation instructions mentioned this fact, but apparently some 80% of the customers missed that fact and had to instead submit to abuse via the company’s tech support line.

Whether it’s a bug in the product, a bug in the documentation, or a bug in our understanding of the user community, it’s still the team’s problem, not the user’s.

Then there was the case of the expensive manufacturing shop-floor control system that none of the users would use. It seems the first step to using the system was to log on with their name and password, and the majority of the workers in this plant were illiterate. No one have ever bothered to ask them or get their feedback, so a completely useless system was installed. (The developers in question had to retool the entire GUI to be picture-based at huge expense.)

We go to great lengths to get feedback from code using unit tests and such, but it’s all too easy to ignore the feedback from users. So not only do you need to talk to real users (not their managers or a surrogate

such as a business analyst), you need to listen to them.

Even if they sound stupid.

Every complaint holds a truth. Find the truth, and fix the real problem.

What It Feels Like

You don’t get irate or dismissive of stupid complaints; you can look past that and see the real, underlying problem.

Keeping Your Balance

• There is no such thing as a stupid user.

• There is such a thing as a stupid, arrogant developer.

• “That’s just the way it is” is not an answer.

• If the code can’t be fixed, perhaps the documentation and training

can be.

• Your users may have read all the documentation and will remember everything about your application all the time.

But probably not.

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

اصل open-closed

یک توسعه دهنده نرم افزار باید همیشه یک چیز را در ذهنش داشته باشد، در غیر اینصورت باید هزینه زیادی را متحمل شود یا حتی بدتر، باید شاهد مرگ محصولش باشد. تغییر.

مهم نیست که شما کجا کار می کنید، روی چه محصولی کار می کنید و با کدام زبان برنامه نویسی، برنامه نویسی می کنید. یک چیز، همیشه می تواند رخ بدهد. تغییر.

تنها یک چیز تغییر نمی کند. تغییر.

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

اصل open-closed

موجودیت های نرم افزاری برای نمونه کلاس ها، توابع و پیمانه ها باید برای توسعه باز باشند(اجازه داشته باشند)، اما برای تغییر باید بسته باشند(اجازه تغییر را ندارند).

یک تشبیه زیبا(فکر می کنم به زبان اصلی خیلی زیباتر است.)

Code should be closed(to change) like the lotus in the evening. Yet open(to extension) like the lotus flower in the morning.

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

فرض کنید که شما یک نرم افزاری نقاشی ساده می خواهید طراحی کنید که قابلیت رسم شکلهای مختلف را داشته باشد.

یک طراحی می تواند به این صورت باشد که شما یک کلاس Shape تعریف می کنید، که اشکال دیگر از آن کلاس به ارث می برند، و یک کلاس دیگر مثلا با نام DrawManager تعریف می کنید که لیست اشیاء را نگهداری می کنید و مسئول رسم اشکال مختلف بر روی صفحه نمایش است. مثلا متدی یا نام DrawAllShape داریم که با توجه به هر نوع هر شکل تابع مخصوص رسم ان شکل را فراخوانی می کند. در این متد ما کدی شبیه کد پایین خواهیم داشت.

If TypeOf S Is Circle Then

DrawCircle()

ElseIf TypeOf S Is Triangle Then

DrawTriangle()

Elseif

End If

بعد از مدتی نیاز پیدا می کنیم که اشکال جدید را به برنامه اضافه کنیم. برای اینکار ما کلاس های جدید را به برنامه اضافه می کنیم، و می رسیم به نقطه منفی کار، ما باید در کلاس DrawManager تغییرات انجام دهیم، متدهای جدیدی را باید به این کلاس اضافه کنیم تا رسم اشکال جدید را انجام دهد و کد متد DrawAllShape را تغییر دهیم تا در صورت وجود شکل های جدید، آنها را رسم کند. بعد از مدت متد DrawAllShape پر از جملات شرطی خواهد بود و همچنین تعداد زیادی متد خواهیم داشت که مدیریت و تغییر این کلاس را مشکل خواهد کرد.

حالا تصور کنید که کلاس انتزاعی یا یک اینترفیس به نام Shape تعریف کرده ایم که دارای یک متد به نام Draw می باشد، و تمام اشکال این متد را به ارث می براند و متد Draw را بازنویسی می کنند. در این حالت هر شکلی  جدیدی به برنامه اضافه شود، کلاس shape را به ارث می برد و متد Draw را بازنویسی می کند و نیازی نیست که در کلاس DrawManager تغییری ایجاد کنم و این کلاس، تنها متد Draw هر شکل را برای رسم آن شکل فراخوانی می کند. همانطوریکه مشاهده کردید ما در این حالت در کد مربوط به هیچ یک از کلاس های موجود تغییری ایجاد نکردیم اما برنامه خود را توسعه دادیم.

در بسیاری از الگوهای طراحی یکی از مهمترین ویژگیهای که در نظر گرفته شده است، اصل open-closed می باشد. برای نمونه می توانید الگوی TEMPLATE را بررسی کنید. ما باید بعضی از تغییراتی که می تواند در سیستم رخ دهد را، پیش بینی کنیم و با استفاده از مفهوم abstractions از سیستم خود در مقابل این تغییرات حفاظت کنیم. در واقع می توان گفت که کلید اصل open-closed دو مفهوم abstractions و encapsulation می باشد.

الگوی Mediator

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

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

برای مثال فرم زیر را در نظر بگیرید، این فرم برای رزور یک اتاق مهمانی در یک هتل استفاده می شود، طرز عملکرد فرم در زیر توضیح داده شده است.

هنگامیکه پنجره برای اولین بار نمایش داده می شود، فقط فیلد مربوط به تعداد مهمان ها و دکمه برگشت فعال است. کنترل های تاریخ، ساعت شروع و ساعت اتمام زمانی فعال می شوند که کاربر تعداد مهمان ها را وارد کند. اما فقط زمانهای را می تواند وارد کند که در آن موقع اتاقی با آن سایز موجود باشد. سپس گزینه سرویس ها فعال می شود. اگر تعداد مهمان ها پاک شود، باید تمام گزینه ها پاک و غیر فعال شوند.

ساعت شروع باید کوچکتر از ساعت اتمام باشد.

هنگامیکه کاربر تعداد مهمانها و ساعت و تاریخ را وارد می کند و یک نوع سرویس را انتخاب کرد، لیست غذا ها فعال می شود. با توجه به تاریخ، ساعت و نوع سرویس، لیست غذاهای ارائه شده متفاوت خواهد بود.

هنگامیکه حداقل یک نوع غذا انتخاب شد، و داده ها دیگر معتبر بودند، دکمه رزور فعال می شود.

شکل بالا، ارتباطات و روابط موجود بین اشیاء روی فرم را نشان می دهد. همانطوریکه داده می شود، هر شی حداقل دارای 2 وابستگی است. همانطوریکه در بالا نیز گفته شده، وابستگی باعث پیچیده شدن منطق برنامه خواهد شد و این نگهداری سیستم را مشکل تر خواهد کرد و قابلیت استقاده مجدد را نیز کاهش خواهد داد. برای مثال تغییر در یکی از کلاس ها ممکن است، به تغییر در سایر کلاس ها منجر شود. شما برای حل این مشکل و کاهش تعداد وابستگی ها چه پیشنهادی دارید؟

برای حل مشکل می توانیم، مانند مثال اول عمل کنیم، یعنی دوستی را ایجاد کنیم که همه به جای کسانی که می خواهند با آنها ارتباط برقرار کنند، فقط با او ارتباط برقرار کند.یعنی در مثال دوم، ما یک کلاس جدید ایجاد کنیم که، به جای اینکه کلاس ها با یکدیگر بطور مستقیم ارتباط برقرار کنند، با کلاس جدید ارتباط بر قرار کنند و کلاس جدید مسئولیت ارتباط با کلاس دیگر را بعهده بگیرید. روشی که برای حل مسئله مطرح شد، الگوی Mediator نام دارد. در واقع این کلاس مسئولیت، مدیریت وابستگی ها را بعهده می گیرد. و با این کار تمام اشیاء، فقط یک وابستگی دارند آن هم با کلاس Mediator. شکل زیر نحوه ارتباطات مثال 2 را، بعد از اعمال شی Mediator را نشان می دهد.

حالا زمانیکه یکی شی می خواهد با شی دیگر ارتباط برقرار کند، پیام خود را به کلاس Mediator، ارسال می کند. و کلاس Mediator همانند یک مسیریاب آن را به شی مورد نظر ارسال می کند. با استفاده از این الگو می توانیم به مزایا زیر دست یابیم:

  1. سادگی تغییر در برنامه : با استفاده از این الگو وابستگی میان کلاس های مختلف کاهش می یابد و در اکثر موارد فقط با تغییر در کلاس Mediator و یا ایجاد زیر کلاس های از این کلاس، می توانیم تغییرات مورد نظر را اعمال کنیم بدون اینکه تغییری در کلاس های دیگر بدهیم.
  2. افزایش قابلیت استفاده مجدد: با کاهش وابستگی میان کلاس، قابلیت استفاده مجدد کلاس ها افزایش می یابد.

ولی باید توجه داشت که کلاس Mediator باعث کاهش پیچیدگی وابستگی بین کلاس ها می شود، اما این پیچیدگی به درون ساختار Mediator منتقل می شود و ممکن است باعث شود که تغییر آن مشکل شود.

نمودار UML الگو ی Mediator

در نمودار بالا شی Mediator، یک اینترفیس برای ارتباط با اشیاء Colleague تعریف می کند که این اینترفیس توسط کلاس ConcreteMediator پیاده سازی می شود. و Colleague کلاس ها، کلاس های هستند که باهم ارتباط داشتند و ما این ارتباط و وابستگی را از آنها جدا کردم و در کلاس Mediator قرار دادیم.

الگوی Memento

نمی دانم تا بحال پشت کامیوتر خودتان نشستید تا یک مرحله از یک بازی کامپیوتری را به پایان برساند یا نه؟ اما کسانی که اینکار را انجام دادند تصور کنند یک بازی استراتژیک مانند کمانندو ها را بازی می کنند اما بازی بدون قابلیت ذخیره کردن ارائه شده است. در این حالت حتما اکثر افراد این بازی را خیلی زود کنار خواهند گذاشت چون واقعا کار کاربر خیلی سخت خواهد شد. پس اگر روزی قرار باشد یک بازی کامپیوتری را طراحی و پیاده سازی کنیم برای برآورده کردن نیاز های کاربر حتما باید بازی را با قابلیت ذخیره کردن طراحی و پیاده سازی کنیم.

اجازه بدهید یکبار دیگر مسئله را تعریف کنیم: فرضی کنید شما در حال طراحی یک بازی هستید. این بازی باید با قابلیتی  ارائه شود که کاربر در هر قسمتی از بازی خواست بتوانید بازی را در آن نقطه ذخیره کنید و سپس هر زمانی که خواست بتواند بازی را از همان نقطه ای که ذخیره کرده است ادامه دهید. راه حل و طراحی شما برای این مسئله چست و چگونه می تواند باشد؟

یا یک مسئله دیگر: تصور کنید شما در حال طراحی یک فروشگاه الکترونیکی برای یک شرکت هستید. و یکی از ویژگیهای در خواست شده از طرف ذی النفعان سیستم این است که، هنگامیکه یک کاربر وارد فروشگاه می شود و اجناس مورد نیاز خود را به سبد خریدش اضافه می کند، اما قبل از اینکه سفارش خود را تائید کند از فروشگاه خارج می شود. سیستم باید قابلیت  این را داشت باشد که هنگام ورود بعدی همان کاربر، آیتم های موجود در سبد خرید قبلی را بازیابی کند و در سبد خرید مشتری قراد دهد.

در هر دو مسئله بالا، کار ما ذخیره حالت موجود اشیاء و سپس بازیابی آن حالت در صورت نیاز هست. یک راه حل موجود و خوب برای مسائل بالا و شبیه آنها، الگوی Memento است. که نحوه عملکرد آنرا، برسی خواهیم کرد.

نمودار UML، این الگو بصورت زیر است:

همانطوریکه در بالا اشاره شد، ما نیاز داریم تا حالت یک شی را ذخیره و بازیابی کنیم، این شی با نام originator در این الگو مشخص می شود. اما نحوه ذخیره کردن وضعیت شی موجود به این صورت است که زمانیکه برنامه Client درخواست ذ   خیره کردن را از شی originator می کند. این شی (originator)، تمام صفاتی را که برای بازیابی حالتش نیاز است را، در یک شی دیگر به نام Memento قرار می دهد و آن را به Client ازسال میکند (در نمودار مقدار صفت state از شی originator، در مقدار صفت stateشی Memento قرار می گیرد.). ما نیاز داریم تا اشیاء از نوع Memento را، نگهداری و مدیریت کنیم. برای اینکار از کلاسی به نام caretaker، استفاده می کنیم. زمانیکه یک شی Mementoایجاد می شود، آن شی به مجموعه اشیاء Caretaker اضافه می شود. وقتی که یک عمل undo انجام می شود شی Caretaker با یک شی دیگر (client)، همکاری می کند تا یک شی Memento انتخاب شود. بعد از انتخاب شی Memento ، آن شی متد setMemento شی Originator را فراخوانی می کند تا حالت انتخاب شده را بازیابی کند.

فرضی کنید شما در حال طراحی یک برنامه ویرایشگر متن هستید، و یکی از نیازهای مطرح شده توسط کاربران این مورد است که وقتی آنها قسمتی از یک متن را کپی می کنند، آن قسمت به یک لیست اضافه شود و نمایش داده شود. سپس زمانیکه کاربر به یکی از متن های کپی شده نیاز داشت، یکی از آنها از لیست انتخاب کند تا متن انتخاب شده به متن اصلی اضافه شود(عمل paste). دقیقا چیز شبیه clipboard برنامه Microsoft Office Word.

می خواهیم این خواسته را توسط الگوی Memento، طراحی کنیم. در این مثال شی که ما نیاز داریم، حالتش را ذخیره کنیم و سپس در صورت نیاز بازیابی کنیم، شی Clipboard است.

کلاس originator که کد مربوط به Clipboard را پیاده سازی می کند. صفت _Clipboard ، بیانگر حالت این شی است و برای بازیابی آن باید این صفت را ذخیره کنیم.

Public Class originator

Private _Clipboard As String

Public Property Clipboard() As String

Get

Return _Clipboard

End Get

Set(ByVal value As String)

_Clipboard = value

End Set

End Property

Public Function createMemento() As memento

Return New memento(_Clipboard)

End Function

Public Sub setMemento(ByVal _memento As memento)

_Clipboard = _memento.Clipboard

End Sub

End Class

کلاس memento که برای ذخیره اطلاعات مورد نیاز برای یازیابی حالت یک نمونه از شی originator به کار می رود.

Public Class memento

Private _Clipboard As String

Public Sub New(ByVal Data As String)

_Clipboard = Data

End Sub

Public Property Clipboard() As String

Get

Return _Clipboard

End Get

Set(ByVal value As String)

_Clipboard = value

End Set

End Property

End Class

کلاس caretaker برای نگهداری نمونه های مختلفی از کلاس memento به کار می رود. در ا ینجا برای نگهداری این نمونه ها از ArrayList استفاد شده است. تو سط متد list، مجموعه اشیایی memento برای نمایش به کاربر برگشت داده می شود. تا کاربر یکی از آنها را در صورت نیاز انتخاب کند.

Public Class caretaker

Private memento As New ArrayList

Public Sub Add(ByVal _memento As memento)

memento.Add(_memento)

End Sub

Public Function List() As ArrayList

Return memento

End Function

End Class

برای تست کلاس های بالا از یک فرم به نام FrmTest استفاده شده است. که یک کنترل ListBox بر روی آن قرار دارد تا مقادیر موجود در هر کدام از نمونه های شی memento را نمایش دهد. تا کاربر بتواند حالت مورد نیاز خود را از میان آنها انتخاب کند.

Public Class FrmTest

Dim Ins As New originator

Dim List As New caretaker

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

Ins.Clipboard = “Ali”

List.Add(Ins.createMemento())

Ins.Clipboard = “asd”

List.Add(Ins.createMemento())

Ins.Clipboard = “sdf”

List.Add(Ins.createMemento())

Me.ListBox1.DataSource = List.List

Me.ListBox1.DisplayMember = “Clipboard”

End Sub

Private Sub ListBox1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles ListBox1.Click

Ins.setMemento(List.List(Me.ListBox1.SelectedIndex))

End Sub

End Class

توجه:  در پیاده سازی مثال بالا، بعضی از قوانین شی گرایی نادیده گرفته شده است.(تصحیح به عهده دوستان)

مدلسازی پایگاه داده از روی نمودار کلاس UML

رابطه وراثت((inheritance :

برای تبدیل رابطه وراثت از مدل شی گرا به مدل رابطه ای چندین روش مختلف وجود دارد. که به بررسی هر یک از روش ها، مزایا و معایب آنها خواهیم پرداخت.

روش اول:

در این روش برای کل سلسله مراتب کلاس، یک جدول در نظر می گیریم. که ساختار جدول به صورت زیر خواهد بود.

{صفات سوپر کلاس، صفات مختص زیر کلاس ها و یک فیلد نوع کلاس (موجودیت)}

فیلد نوع برای ذخیره اینکه رکورد مورد نظر مربوط به اطلاعات کدام کلاس است به کار می رود.

برای مثال برای نمودار بالا، ساختار زیر را خواهیم داشت:

{شماره شناسایی، نام، نام خانوادگی، مقطع، رشته، درجه، سابقه تحصیل و نوع}

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

 

روش دوم:

در این روش برای هر زیر کلاس یک جدول در نظر می گیریم. که شمای هر جدول به صورت زیر خواهد بود:

{صفات سوپر کلاس و صفات مختص زیر کلاس}

برای مثال برای همان نمودار مثال قبل دو جدول زیر را خواهیم داشت:

استاد{شماره شناسایی، نام، نام خانوادگی،درجه، سابقه تحصیل }

دانشجو{شماره شناسایی، نام، نام خانوادگی، مقطع، رشته }

در این روش بعضی از افزونگی ها را خواهیم داشت.برای مثال تصور کنید که شخص را داریم که هم استاد هست و هم در یک رشته دیگر به عنوان دانشجو تحصیل می کند. در این حالت صفاتی مانند نام و نام خانوادگی برای یک شخص دوباره ذخیره می شود.

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

یک عیب دیگر این روش اینست که اگر در صفات سوپر کلاس تغییراتی داده شود نیاز است که کلیه جدول های مربوط به زیر کلاس ها نیز اصلاح شود.

اما مزیت این روش نسبت به روش اول اینست که در این روش دیگر ستونهای با مقادیر Null را نخواهیم داشت.

 

روش سوم:

در این روش برای سوپر کلاس یک کلاس جداگانه در نظر می گیریم که شامل صفات سوپر کلاس می باشد. و برای هر زیر کلاس نیز یک جدول جداگانه در نظر می گیریم. که شامل صفات مختص آن زیر کلاس به همراه کلید اصلی جدول مربوط به سوپر کلاس.

برای مثال برای نمودار مثال اول، اگر صفت شماره شناسایی را برای هر شخص منحصر بفرد در نظر بگیریم.خواهیم داشت:

شخص{شماره شناسایی، نام، نام خانوادگی}

استاد{شماره شناسایی، درجه، سابقه تحصیل}

دانشجو{شماره شناسایی، مقطع، رشته}

این روش بهترین گزینه برای ما می باشد.زیرا دقیقا هر کلاس را به یک جدول جداگانه و مستقل نگاشت می کند. و هر تغییری در یک کلاس فقط در جدول مربوط به آن کلاس تاثیر خواهد گذاشت و بر خلاف دو روش قبلی، روی جدول های دیگر تاثیر نخواهد گذاشت. در این روش نه افزونگی داده داریم و نه ستونی با مقدار Null.

 

رابطه association:

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

اما برای نگاشت این رابطه بین دو کلاس به رابطه بین دو جدول(برای هر کلاس یک جدول در نظر می گیریم.) چه کاری باید انجام دهیم؟

دقیقا مشابه کاری را که توی پیاده سازی این رابطه انجام می دهیم. اینجا نیز انجام می دهیم. کلید اصلی جدول مربوط به کلاسی را که نیاز داریم اطلاعاتی از آن را داشته باشیم عنوان کلید خارجی استفاده می کنیم. و به جدول کلاسی که این اطلاعات را نیاز دارد اضافه می کنیم.

 

برای مثال برای نمودار شکل بالا جدول های زیر را خواهیم داشت.

آدرس{کد پست ده رقمی، شهر، خیابان و …}

شخص{کد پستی ده رقمی و صفات کلاس شخص}

 

رابطه تجمع (aggregation) و رابطه ترکیب (composition):

رابطه تجمع، یک رابطه بین یک واحد کل و جزء است. در این رابطه، بزای موجودیت کل، یک جدول و برای هر یک از کلاس های جزء نیز یک جدول طراحی می کنیم. در هر کدام از جدول های مربوط به اجزاء جزء، کلید اصلی (یا یکی از کلید های کاندید) جدول مربوط به واحد کل را می آوریم.

 

برای نمونه برای شکل بالا خواهیم داشت:

ماشین{صفات مربوط به ماشین}

تایر{کلید اصلی جدول ماشین و صفات مربوط به تایر}

موتور{کلید اصلی جدول ماشین و صفات مربوط به موتور}

در رابطه تجمع، شی جز به شی کل وابسته نیست. پس با حذف شی کل، اجزاء تشکیل دهنده آن از بین نمی روند. بلکه باید مقدار مربوط به صفت کلید شی کل در اشیاء جزء پاک شوند.

تبدیل رابطه ترکیب نیز شبیه رابطه تجمع است اما به یک تفاوت. چون در رابطه تجمع اشیاء تشکیل دهنده کل به واحد کل وابسته هستند ونمی توانند بدون آن به حیاتشان ادامه بدهند. با حدف شی کل، اشیاء جزء نیز باید حذف شوند. در واقع ما در اینجا باید یکپارچکی ارجاعی (Referential Integrity) را رعایت کنیم.

در اینجا من به در خواست یکی از دوستان فقط به بررسی روابط بین کلاس ها پرداختم. ولی دوستانی که به این موضوع علاقه دارند می توانند به مقاله Database Modelling in UML در سایت www.sparxsystems.com.au مراجعه کنند.

سر فصل و منابع درس مهندسی نرم افزار

سرفصل و منابعی که توسط وزارت علوم برای درس مهندسی نرم افزار 1 و 2 در نظر گرفته شده است.

 

مهندسی نرم افزار 1

سر فصل مطالب

بحران نرم افزار، علل نیاز به متدلوژی و فرآیند تولید، چرخه حیات سیستم(مشتمل بر تحلیل خواسته ها، طراحی کلی، طراحی جزیی، پیاده سازی، تبدیل و نگهداری سیستم)

مفاهیم تحلیل سیستم ها، سیستم های اطلاعاتی ساختیافته، مدل فیزیکی جریان داده های سیستم موجود، مدل منطقی جریان داده های سیستم های پیشنهادی، مدل فیزیکی جریان داده های سیستم های پیشنهادی، مشخصات دقیق خواسته ها، مشخصات فیزیکی داده ها، امکان سنجی سیستم ها با توجه به سه مولفه تکنولوژی – نیروی انسانی و منابع مالی و زمانی، تهیه گزارش امکان سنجی، نمونه سازی، طراحی کلی سیستم شامل طراحی فایل ها یا بانکهای اطلاعاتی، طراحی فرمهای ورودی و گزارشات نهائی، طراحی واسط کاربر، طراحی ساختمان نرم افزار، تعیین مشخصات پردازشها یا عملیات سیستم، تعیین مشخصات فرهنگ داده ها، تهیه گزارش طراحی کلی سیستم.

معرفی روشهای جمع آوری اطلاعات، معرفی روشهای تخمین هزینه و برآورد زمان جهت انجام هر یک از مراحل سیستم، معرفی روشها و ابزار مدیریت پروژه، معرفی ابزار های کمک به تحلیل سیستم، معرفی ابزارهای کمک به طراحی سیستم، معرفی بخش اول CASE

مراجع

1.       Bentley, Barlow and Toppan, System Analysis and Design Methods, 199.

2.       Yourdon, Modern Structured Analysis, Perntice-Hall, 1989.

3.       Fitsgerald and A. Fitzgerald, Fundamentals of System Analysis, 3rd Edition, John Wiley, 1987.

4.       Hawryszkiewgcz, Introduction to System Analysis and Design, 2nd Edition, Prentice-Hall, 1992.

5.       E.M.Awad, System Analysis and Design, 2nd Edition 1985.

6.        K.E.Kendall and J.E. Kendall, Systems Analysis and Design, 2nd Edition, Prentice-Hall, 1992.

7.       B. Boehm, Software Engineering, 4th Edition, Addison-Wesley, 1996.

8.       A. Sommerville, Software Engineering, 4th Edition, Addison-Wesley, 1996.

9.        R. S. Pressman, Software Engineering, A Practitioners Approach, 4th Edition, Mc Graw Hill, 1996.

 

مهندسی نرم افزار 2

سر فصل مطالب

تعریف مهندسی نرم افزار، نقش و اهداف مهندسی نرم افزار در تولید سیستم های کا مپیوتری، فراروند ساخت نرم افزار(از تعیین مشخصات تا پیاده سازی)، فراروند ایجاد نرم افزار، مدلهای چرخه حیات سیستم، روشهای طراحی نرم افزار(عملکردگرا، فراروندگرا، داده گرا، شی گرا)، استراتژهای پیاده سازی نرم افزار(ملاخصات پیاده سازی، ملاحظات زبان برنامه نویسی در تولید نرم افزار)، تکنیک های مستند سازی، آزمایش و وارسی و تشخیص اعتبار نرم افزار، صحت و قابلیت اطمینان نرم افزار، روشهای اشکال زدائی و دفاع در مقابل بروز اشکال، بهبود کارائی، طراحی نرم افزار ها بطورئکه قابلیت استفاده مجدد را داشته باشند، معرفی ابزارهای پشتیبانی، استفاده مجدد نرم افزارها، نگهداری و توسعه نرم افزار و اعمال تغییرات، ملزومات محیطی تولید نرم افزار(ابزارهای کمک به طراحی، ابزارهای کمک به پیاده سازی و ابزارهای کمک به آزمایش و وارسی)، معرفی بخش دوم CASE .

مراجع

1.       A. Sommerville, Software Engineering, 4th Edition, Addison-Wesley, 1996.

2.       R. S. Pressman, Software Engineering, A Practitioners Approach, 4th Edition, Mc Graw Hill, 1996.

3.       D. Bell, I. Morrey and J. Pavgh, Software Engineering, A Practical Approach, Prentice-Hall, 1992.

4.       I. Jacobson, Object-Oriented Software Engineering, John Wiley, 1993. 

 

الگوی Façade (نما)

الگوی Façade (نما):

الگوی نما در سیستم های استفاده می شود که توسعه دهندگان می خواهند پیچیدگی یک سیستم را در یک کلاس (در بعضی مواقع چند کلاس) مخفی کنند و با استفاده از این کلاس و یا کلاس ها به عنوان واسط و میانجی، پیچیدگی سیستم را کاهش دهند.

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

یک روش غلبه بر این وضعیت، ایجاد کلاس façade می باشد، که واسطی را به زیر سیستم ایجاد می کند و این کلاس به عنوان نماینده زیرسیستم مورد نظر با زیر سیستم های دیگر عمل می کند. به این ترتیب، تغییر در پیاده سازی کلاس های زیر سیستم اثر محدودی بر زیر سیستم های دیگر دارد. و اگر تغییری در کلاس ها صورت بگیرد، فقط لازم است نقاطی در زیر سیستم های دیگر پیدا شود که در آنها، پیامی به نمونه های از کلاس façade ارسال شده است.

حالا با بررسی چند مثال می توانیم تصویری بهتری از این الگو به دست بیاوریم.

تصور کنید شما به عنوان مدیر پروژه برای یک پروژه نسبتا بزرگ انتخاب شده اید. در حالت اول شما خودتان وظیفه دارید مسئولیت تک و تک افراد پروژه را به آنها بگوید و وظایف واگذر شده به آنها را تحویل بگیرید. در این حالت شما وظیفه دارید با تک و تک افراد ارتباط برقرار کنید و همچنین برای بازخواست وظایف شما باید نحوه ارتباط این افراد را با یکدیگر بدانید. در حالت دوم یک نفر به عنوان سر گروه انتخاب می شود و شما مسئولیت ها واگذر شده را به او اعلام می کنید و برای تحویل وظایف فقط از او بازخواست می کنید. حالا دو حالت را باهم مقایسه کنید در کدام حالت پیچیدگی و حجم کاری شما کم است؟ البته که حالت دوم. در حالت دوم در واقع ما از الگوی façade استفاده کردیم. سر گروه در این حالت به عنوان کلاس façade است.

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

برای مثال آخر فرض کنید شما وظیفه دارید یک برنامه برای ایجاد و ارسال ایمیل بنویسید کلاس های که ممکن است برای اینکار در نظر بگیرید می تواند به صورت شکل زیر باشد.

·         کلاس MessageBody: این کلاس شامل بدنه پیام خواهد بود.

·         کلاس Attachment: این کلاس نمونه سازی می شود تا یک کلاس MessageBody در صورت نیاز شامل فایل پیوست باشد.

·         کلاس MessageHeader: این کلاس نمونه سازی می شود تا شامل اطلاعات سرآیند فایل باشد مانند From,To,Subject,….

·         کلاس Message: این کلاس نمونه سازی می شود تا دو کلاس MessageBody و MessageHeader را به هم متصل کند (پیوند بزند).

·         کلاس Security: این کلاس نمونه سازی می شود تا در صورت نیاز پیام ارسالی رمز گذاری شود.

·         کلاس MessageSender: این کلاس نونه سازی می شود تا در آخر پیام مورد نظر را به سرور مربوطه ارسال کند.

شکل زیر نمودار کلاس های بالا را همراه با ارتباطات آنها نشان می دهد.

 

 

 

با مشاهده تصویر بالا می تواند حدس بزند که کار با کلاس های که برای اینکار در نظر گرفته اید، کلاس client را می تواند بیش از حد پیچیده کند. برای استفاده از این کلاس ها، کلاس کلاینت باید با این 6 کلاس و همچنین باید با روابط بین آنها آشنا باشد. دوباره برای کاهش پیچیدگی می توانیم از الگوی façade استفاده کنیم یعنی برای کاهش پیچیدگی از یک کلاس جدید اتفاده می کنیم. طرح جدید می تواند به شکل زیر باشد.

 

 

نمودار کلاس الگوی نما:

نمودار کلاس الگو به صورت زیر می باشد.

اجزاء تشکیل دهنده الگو:

 

کلاس ها و اشیاء تشکیل دهنده این الگو عبارتند از:

·         کلاس façade :

  • این کلاس می داند که کلاس های زیر سیستم باید به پیام دریافت شده پاسخ دهند.
  • پیام های دریافت شده را به شی مناسب برای پاسخگوئی ارسال می کند.

·         کلاس های زیر سیستم:

  • کلاس های زیر سیستم از وجود کلاس façade آگاه نیستند.
  • به پیام های ارسال شده توسط کلاس façade پاسخ می دهند.

Factory Patterns (قسمت اول)

مفهوم Factory (کارخانه)، دقیقا از معنی لغوی آن مشخص است. کارخانه مکانی است که در آن کالاها و محصولاتی تولید می شود. و در بحث الگوهای طراحی، یک Factory کلاسی است که نمونه های از کلاس های دیگر را با توجه به پارامترهای که برای آن ارسال می شود، ایجاد می کند.

برای ایجاد یک ذهنیت در خودتان می توانید تصور کنید که ما یک فروشگاه پوشاک داریم هر وقت که فروشگاه به لباس خاصی نیاز داشته باشید. اسامی آن را به تولید کننده(Factory) ارسال می کند و تولید کننده با توجه به اسامی ارسال شده آن لباس ها را تولید کرده و به فروشگاه ارسال می کند. در این مثال تولید کننده همان کلاس Factory ما است که با توجه به پارامترهای ارسال شده (لیست پوشاک مورد نظر فروشگاه) لباس مورد نظر (شی موزد نظر) را تولید می کند و به مشتری ارسال می کند.

نمونه کد اول در VB.NET

‘Class Shirt

Public Class Shirt

Protected _Color As String

Protected _Size As String

Public ReadOnly Property Color()

Get

Return _Color

End Get

End Property

Public ReadOnly Property Size()

Get

Return _Size

End Get

End Property

End Class

‘Class Shrit_A

Public Class Shrit_A

Inherits Shirt

Public Sub New()

Me._Color = “Blue”

Me._Size = “XL”

End Sub

End Class

‘Class Shrit_B

Public Class Shirt_B

Inherits Shirt

Public Sub New()

Me._Color = “Red”

Me._Size = “M”

End Sub

End Class

‘Class Factory

Public Class Factory

Public Function GetShirt(ByVal Type As String) As Shirt

If Type = “A” Then

Return New Shrit_A()

Else

Return New Shirt_B()

End If

End Function

End Class

‘Class Store

Public Class Store

Private _OrderType As String

Public Property OrderType()

Get

Return _OrderType

End Get

Set(ByVal value)

_OrderType = value

End Set

End Property

Public Function Order() As Shirt

Dim Ins1 As New Factory

Dim Ins2 As Shirt = Ins1.GetShirt(_OrderType)

Return Ins2

End Function

End Class

نحوه استفاده

Private Sub Cmd_Order_Click(ByVal sender As System.Object, ByVal e As System.EventArgs)

Dim Ins1 As New Store

Dim INs2 As New Shirt

Ins1.OrderType = “A”

INs2 = Ins1.Order()

End Sub