اشتراکها
الگوی طراحی ستاره مرده!
- سیستمهایی که در خفا سفارش داده شده و ساخته میشن با بودجهای غیرقابل تصور
- تعداد معدودی اجازهی استفاده از آنرا دارند و مابقی هم میتونند نگاه کنند؛ البته اگر مجوزش را داشته باشند!
- بعد از مدتی که بودجه مصرف شد پروژه متوقف میشه
- دوباره نگارش 2 آن با تکرار مراحل قبل شروع خواهد شد.
چیزی مثل همون سیستمهای «لوکس» و «غیرضرور»
- تعداد معدودی اجازهی استفاده از آنرا دارند و مابقی هم میتونند نگاه کنند؛ البته اگر مجوزش را داشته باشند!
- بعد از مدتی که بودجه مصرف شد پروژه متوقف میشه
- دوباره نگارش 2 آن با تکرار مراحل قبل شروع خواهد شد.
چیزی مثل همون سیستمهای «لوکس» و «غیرضرور»
البته سایت Smashing Magazine، مقالههای زیاد و بسیار مفیدی در این موارد داره.
به عنوان نمونه:
New Approaches To Designing Log-In Forms
و همچنین در قسمت Related Articles که در پایین مقاله هایی از این دست وجود داره.
به عنوان نمونه:
New Approaches To Designing Log-In Forms
و همچنین در قسمت Related Articles که در پایین مقاله هایی از این دست وجود داره.
اشتراکها
برگه تقلب معماری نرم افزار!
اشتراکها
الگوهای طراحی 1/3
اگر علاقمند هستید که object-oriented یا برنامه نویسی n-tire را اصولی و منطقی یاد بگیری پیشنهاد میکنم از این فریمورک استفاده کنید.
دانلود سورس
دانلود کد و راهنما
دانلود سورس
دانلود کد و راهنما
الگوی command، اجازهی کپسوله سازی درخواستها و عملیات را در شیءهای جداگانهای میدهد. این الگو، شیءهایی که درخواستها را ارسال میکنند، از شیءهایی که مسئول اجرا کردن درخواستها هستند، جدا میکند.
یک مثال را در نظر بگیرید؛ جائیکه یک کلاینت قرار است، دسترسی به متدهای یک API را به صورت مستقیم داشته باشد. چه اتفاقی خواهد افتاد اگر پیاده سازی آن APIها تغییر کند؟ هر جائیکه API، در حال استفاده شدن است، باید تغییرات صورت گیرد. برای اجتناب از این کار، ما از abstraction بهره خواهیم برد و سپس شیءهای درخواست کننده را از پیاده سازی درخواستها، جدا میکنیم .
دیاگرام بالا، ماهیت این الگو را نمایش میدهد:
- Invoker: از Command میخواهد که درخواست را اجرا کند.
- Command: اطلاعاتی را در رابطه با action، به همراه دارد و هم چنین bind کردن آن به receiver؛ همراه با فراخوانی کردن عملیات مربوطه بر روی command.
- Reciever: میداند که چگونه عملیات مرتبط با command مورد نظر را انجام دهد.
- Client: یک command را ایجاد میکند و receiver را مشخص میکند؛ چه کسی قرار است این command را دریافت کند.
اجازه بدهید یک مثال واقعی، بر اساس دیاگرام بالا جهت درک بهتر داشته باشیم:
مثال:
class Command { execute() {}; } //TurnOnPrinter command class TurnOnPrinter extends Command { constructor(printingMachine) { super(); this.printingMachine = printingMachine; this.commandName = "turn on" } execute() { this.printingMachine.turnOn(); } } //TurnOffPrinter command class TurnOffPrinter extends Command { constructor(printingMachine) { super(); this.printingMachine = printingMachine; this.commandName = "turn off" } execute() { this.printingMachine.turnOff(); } } //Print command class Print extends Command { constructor(printingMachine) { super(); this.printingMachine = printingMachine; this.commandName = "print" } execute() { this.printingMachine.print(); } } //Invoker class PrinterControlPanel { pressButton(command) { console.log(`Pressing ${command.commandName} button`); command.execute(); } } //Reciever: class PrintingMachine { turnOn() { console.log('Printing machine has been turned on'); } turnOff() { console.log('Printing machine has been turned off'); } print(){ console.log('The printer is printing your document') } } const printingMachine = new PrintingMachine(); const turnOnCommand = new TurnOnPrinter(printingMachine); const turnOffCommand = new TurnOffPrinter(printingMachine); const printCommand = new Print(printingMachine) const controlPanel = new PrinterControlPanel(); controlPanel.pressButton(turnOnCommand); controlPanel.pressButton(turnOffCommand); controlPanel.pressButton(printCommand);
در مثال بالا، یک کلاس به نام PrintingMachine داریم:
class PrintingMachine { turnOn() { console.log('Printing machine has been turned on'); } turnOff() { console.log('Printing machine has been turned off'); } print(){ console.log('The printer is printing your document') } }
در اینجا میتوانیم یکی از عملیات زیر را با استفاده از printingMachine انجام دهیم:
- turnOn: روشن کردن ماشین (printer)
- turnOff: خاموش کردن ماشین (printer)
- print: چاپ کردن صفحه با استفاده از ماشین (printer)
هر زمانکه ماشین چاپ (printing machine)، یک command را برای هر یک از این عملیات دریافت میکند، آن را اجرا میکند. اکنون میتوانیم متوجه شویم که 3 نوع command که یک کاربر میتواند به printer ارسال کند، وجود دارند:
class TurnOnPrinter extends Command {/*code*/} class TurnOffPrinter extends Command {/*code*/} class Print extends Command {/*code*/}
هر 3 کلاس بالا، یک abstract کلاس به نام Command را extend میکنند:
class Command { execute() {}; }
کلاسهای فرزند، تابع execute را ارث بری میکنند و در نتیجه، آن را تعریف میکنند. اجازه دهید که در ادامه، نگاهی به هر کدام از commandها داشته باشیم.
class TurnOnPrinter extends Command { constructor(printingMachine) { super(); this.printingMachine = printingMachine; this.commandName = "turn on" } execute() { this.printingMachine.turnOn(); } }
در اینجا سازندهی کلاس، printingMachine را به عنوان پارامتر دریافت میکند و همچنین متغیر commandName را مقدار دهی اولیه میکند که در اینجا به "turn on" تنظیم شدهاست.
سپس تابع execute را تعریف میکند که کار روشن کردن ماشین را وقتی که فراخوانی شود، انجام خواهد داد.
commandهای TurnOffPrinter و Print، تعاریفی مشابه به TurnOnPrinter دارند که در بالا توضیح داده شد. برای TurnOffPrinter ، command متغیر commandName به مقدار "turn off" و برای Print ، command به مقدار print تنظیم شدهاست.
class TurnOffPrinter extends Command { //code... this.commandName = "turn off" //code.. } class Print extends Command { //code... this.commandName = "print" //code.. }
به طور مشابه آنها تابع execute را تعریف میکنند که عملیات خاموش کردن ماشین، وقتی که TurnOffPrinter ، command اجرا شود، انجام میشود و عملیات چاپ زمانیکه
Print ، command اجرا شود، انجام میشود.
class TurnOffPrinter extends Command { //code... execute() { this.printingMachine.turnOff(); } } class Print extends Command { //code... execute() { this.printingMachine.print(); } }
چگونه این commandها فراخوانی میشوند؟
invoker، صفحه کنترل (control panel) برای printer است که دکمههای turn on، turn off و print را دارد و کاربر یک دکمه را برای ارسال یک command فشار خواهد داد.
class PrinterControlPanel { pressButton(command) { console.log(`Pressing ${command.commandName} button`); command.execute(); } }
نگاهی به مثال زیر داشته باشید:
controlPanel.pressButton(turnOnCommand);
در اینجا کاربر دکمه را برای روشن کردن printer فشار میدهد. بعد از فشردن دکمه، تابع execute برای این command اجرا خواهد شد و در ادامه شما پیام زیر را خواهید دید:
Printing machine has been turned on
چه زمانی از الگوی command استفاده کنیم:
- اگر میخواهید یک صف درست کنید و درخواستها را در زمانهای متفاوتی اجرا کنید.
- اگر میخواهید عملیاتی از قبیل reset و undo را انجام بدهید.
- اگر میخواهید تاریخچهای از درخواستهای ایجاد شده را داشته باشید.