رادکام
الگوی Command یکی از الگوهای رفتاری می باشد. این الگو برای ارتباط بین اشیا به کار برده می شود. به صورتی که درخواست ها در یک شی سازمان دهی می شوند. این الگو کار را برای کنترل های دستوری راحت تر می کند. الگوی Command یک الگوی رفتاری است. همان طور که گفته شد الگوهای رفتاری جهت ارتباط اشیا با یکدیگر استفاده می شوند. به این صورت که تقاضاها در این نوع الگو در یک شی سازمان دهی می شوند و به همین دلیل می توان آن ها را به راحتی در فعالیت ها استفاده نمود و سازمان دهی و کنترل دستورات آسان تر خواهد شد.
خاصیت الگوی Command باعث شده است که کاربردهای مختلفی از جمله موارد زیر را داشته باشد:
همان طور که در دیاگرام مشخص است نمودار کلاس الگوی Command شامل کلاس های زیر است:
در ادامه ، پیاده سازی این الگو را در یک مثال توضیح می دهیم:
فرض کنید در یک فروشگاه برای برخی محصولات تخفیف هایی قرار داده شده است و بنابراین در محاسبه قیمت محصول این مقدار از قیمت اصلی کسر خواهد شد، از طرفی برای هر محصول مالیات بر ارزش افزوده نیز تعیین شده است که این مقدار از قیمت محصول کسر خواهد شد. بنابراین در صندوق فروشگاه هنگام محاسبه قیمت ممکن است یک یا لیستی از محصولات وجود داشته باشد که برای هر کدام از آن ها باید یک سری عملیات ریاضی پشت سر هم را انجام داد و قیمت را محاسبه نمود.
برای استفاده از الگوی Command برای پیاده سازی محاسبه قیمت محصولات در صندوق می توان کلاس مشتری را به صورت زیر تعریف نمود که در آن یک لیست از محصولات تعریف شده و بر روی آن دو عمل کاهش قیمت بر اثر تخفیف و افزایش قیمت بر اثر مالیات انجام می شود:
class Program
{
static void Main(string[] args)
{
var modifyPrice = new ModifyPrice();
var product = new Product("Phone", 500);
#region Execute Queue commands for product price
var commandList = new List();
commandList.Add(new ProductCommand(product, PriceAction.Decrease, product.Price * 20 / 100));
commandList.Add(new ProductCommand(product, PriceAction.Increase, product.Price * 9 / 100));
ExecuteList(product, modifyPrice, commandList);
Console.WriteLine(product);
Console.WriteLine();
modifyPrice.UndoActions();
Console.WriteLine(product);
#endregion
string line = Console.ReadLine();
}
private static void Execute(Product product, ModifyPrice modifyPrice, ICommand productCommand)
{
modifyPrice.SetCommand(productCommand);
modifyPrice.Invoke();
}
private static void ExecuteList(Product product, ModifyPrice modifyPrice, List productCommand)
{
foreach (var item in productCommand)
{
modifyPrice.SetCommand(item);
modifyPrice.Invoke();
}
}
}
کلاس دریافت کننده نیز به صورت زیر تعریف می شود که در آن الگوریتم ها و متدهای مورد استفاده تعریف می شود:
class Product
{
public string Name { get; set; }
public int Price { get; set; }
public Product(string name, int price)
{
Name = name;
Price = price;
}
public void IncreasePrice(int amount)
{
Price += amount;
Console.WriteLine($"The price for the {Name} has been increased by {amount}$.");
}
public bool DecreasePrice(int amount)
{
if (amount < Price)
{
Price -= amount;
Console.WriteLine($"The price for the {Name} has been decreased by {amount}$.");
return true;
}
else
{
//Console.WriteLine($"The price for the {Name} has not changed.");
return false;
}
}
public override string ToString() => $"Current price for the {Name} product is {Price}$.";
}
کلاس Command کلاسی مجرد است که دستورات مورد نیاز و پارامترها در آن تعریف می شود:
public interface ICommand
{
void ExecuteAction();
void UndoAction();
}
و در کلاس Concrete Command دستورات تعریف شده به صورت زیر پیاده سازی می شوند:
class ProductCommand : ICommand
{
private readonly Product _product;
private readonly PriceAction _priceAction;
private readonly int _amount;
public bool IsCommandExecuted { get; private set; }
public ProductCommand(Product product, PriceAction priceAction, int amount)
{
_product = product;
_priceAction = priceAction;
_amount = amount;
}
public void ExecuteAction()
{
if (_priceAction == PriceAction.Increase)
{
_product.IncreasePrice(_amount);
IsCommandExecuted = true;
}
else
{
IsCommandExecuted = _product.DecreasePrice(_amount);
}
}
public void UndoAction()
{
if (!IsCommandExecuted)
return;
if (_priceAction == PriceAction.Increase)
{
_product.DecreasePrice(_amount);
}
else
{
_product.IncreasePrice(_amount);
}
}
}
کلاس Invoker نیز که مخزن فرامین بوده و زمان اجرای برنامه را مشخص می نماید به صورت زیر قابل پیاده سازی می باشد:
class ModifyPrice
{
private readonly List _commands;
private ICommand _command;
public ModifyPrice()
{
_commands = new List();
}
public void SetCommand(ICommand command) => _command = command;
public void Invoke()
{
_commands.Add(_command);
_command.ExecuteAction();
}
public void UndoActions()
{
foreach (var command in Enumerable.Reverse(_commands))
{
command.UndoAction();
}
}
}
4,337بازدید
دیدگاه کاربران
هنوز دیدگاهی ثبت نشده است.
شما میتوانید درباره این مقاله، دیدگاه خود را ثبت کنید.