درخواست را به عنوان یک شیء کپسوله میکند، از این رو اجازه میدهد تا بتوانید کارخوهها را با درخواستها، صفها و یا لاگهای متفاوت پارامتری کنید.
- کپسوله کردن درخواستها
- پارامتری کردن کلاینت به طوری که بتواند درخواستهای متفاوتی را دریافت کند. برای مثال پیشخدمت در طول روز درخواستهای متفاوتی را دریافت میکند و یا در مثال ریموت کنترل، کنترلر میتواند درخواستهای متفاوتی را دریافت کند.
از این الگو زمانی استفاده کنید که
- نیاز به پشتیبانی از گزارشنویسی (logging) دارید.
- لازم است تاریخچه را مدیریت کنید. (مثل عملیات undo/redo)
- نیاز است تا از تراکنشها پشتیبانی کنید.
- نیاز به callback دارید.
- نیاز است تا درخواستها در زمانهای متفاوت و یا در ترتیبهای متفاوت (صف، پشته و ...) هندل شوند.
- منبع درخواست باید از شیءای که واقعاً درخواست را هندل میکند، جدا (دیکوپلینگ) شوند.
- Command: رابطی برای اجرای عملیات بیان میکند.
- ConcreteCommand
- Client: اشیاء ConcreteCommand را میسازد و receiverهای آنها را تنظیم میکند.
- Invoker: از Command میخواهد که درخواستاش را حمل کند.
- Receiver
- Thread pools: رجوع شود به java.lang.Runnable
- Transactional behavior: قابل برگشت بودن عملیات
- Wizards: به تأخیر انداختن عملیات
- Macro Recording: میتوانیم عملیات متفاوت و پشت سرهم را ضبط کنیم و سپس یکباره آنها را اجرا کنیم. مثل ماکروها در ویرایشگرهای vim و Emacs و یا ماکروهای IDEها.
- Multi-level undo: چون عملیات به صورت شیء در پشته ذخیره میشود هر گاه کاربر بخواهد به اندازهٔ چند مرحله Undo کند، به راحتی با pop کردن اشیاء از پشته و اجرای عملیات undo امکانپذیر است.
- Job queue: تمامی اشیاء command را وارد صف میکنیم و هر کدام را از صف خارج کرده و یک نخ به آنها اختصاص میدهیم تا کار آنها تمام شود.
اگر برای اسلاتی هیچ عملیاتی در نظر نداشته باشیم، میتوانیم یک شیء Null به نام NoCommand درست کنیم و آن را به اسلات مورد نظر متصل کنیم.
اگر بخواهیم چندین فرآیند را به صورت تراکنش انجام دهیم این الگوی طراحی میتواند به ما کمک کند. برای مثال فرض کنید که بخواهیم کارهای زیر را انجام دهیم:
- یک رکورد در دیتابیس ایجاد کن.
- سرویسی را صدا بزن تا تمامی رکوردهای مرتبط را به روزرسانی کند.
- سرویس دیگری را صدا بزن تا عملیات را لاگ کند. برای انجام این عملیات تراکنش گونه، میتوانیم هر عمل را به صورت یک ConcreteCommand طراحی کنیم. که همهٔ این عملیات undo دارند. در آخر هر مرحله، آن کامند را وارد پشته میکنیم. اگر عملیات در مرحلهای شکست بخورد، سپس کامندها را یکی یکی از پشته خارج میکنیم و undo را روی آنها اجرا میکنیم.
منبع: http://stackoverflow.com/a/12153801/225052
فرض کنید که کلی وسیله داریم که هر کدام اینترفیس مخصوص به خود برای روشن و خاموش شدن و به کار افتادن و عملیاتهای مختلف را داشته باشند.
- پنکه : روشن/خاموش/افزایش سرعت/کاهش سرعت
- تلویزیون: روشن/خاموش/شبکهٔ بعدی/شبکهٔ قبلی
- چراغ: روشن/خاموش
- استریو: روشن/خاموش/فعال کردن سیدی/فعال کردن دیویدی/فعال کردن رادیو
میخواهیم یک کنترل از راه دور برای این دستگاهها طراحی کنیم.
- نیازی نیست که کنترلر اینترفیس دستگاههای مختلف را بداند. فقط کافیست که درخواست خودش را برای این دستگاهها ارسال کند.
- با چنین طراحیای هر گاه دستگاه جدیدی اضافه شود به راحتی می توان دکمهٔ جدیدی برای کنترل آن در کنترلر تعریف کرد.
- الگوی طراحی Command درخواست کنندهٔ عمل را از انجامدهندهٔ عمل جدا میکند.
- برای انجام چنین کاری «شیء فرمان» تعریف میکنیم: در خواستها را کپسوله برای اشیاء مختلف کپسوله میکنیم مثلاً اشیائی به صورت زیر خواهیم داشت:
- ضبط صوت را روشن کن (یک شیء است)
- لامپ را خاموش کن (شیء)
- تلویزیون را خاموش کن (شیء)
- مشتری به پیشخدمت درخواست پخت غذای مخصوصی را میدهد.
createOrder()
- پیشخدمت درخواست را از مشتری گرفته
takeOrder()
و به روی میز سرآشپزها بگذاردorderUp()
. - سرآشپز از روی درخواست غذای مورد نظر مشتری را تهیه میکند.
makeBurger()
وmakeShake()
در این روش پیشخدمت از جزئیات با خبر نیست و فقط دستور مشتری را به سرآشپزها منتقل میکند.