رادکام
الگوی Memento یکی از الگوهای رفتاری می باشد. این الگو برای ذخیره وضعیت اشیا و بازگشت به وضعیت قبلی یا بعدی به کار برده می شود. بنابراین می توان برای پیاده سازی Undo و Redo از این الگو استفاده نمود. برای مثال در بازی های کامپیوتری گاهی ممکن است تا مرحله ای پیش رفته و بخواهیم که وضعیت موجود تا آن مرحله را ذخیره کنیم تا در مراجعه بعدی نیازی به شروع از ابتدا نداشته باشیم، در برخی محاسبات و تراکنش های سنگین نیز به دلیل زمان بر و هزینه زیاد ممکن است نیاز به ذخیره تا مرحله خاصی وجود داشته باشد. در این موارد می توان از الگوی Memento استفاده نمود. ذخیره اطلاعات توسط این الگو بسته به نیاز می تواند در حافظه اصلی و یا حافظه های جانبی مثل فایل و... انجام شود و به همین دلیل می تواند هزینه بر باشد. نام دیگر این الگو Token می باشد و به دلیل ذخیره و نگهداری وضعیت ها به Memento به معنی یادداشت یا یادگاری نامگذاری شده است.
از جمله کاربردهای الگوی Memento می توان به موارد زیر اشاره نمود:
در مواردی که نیاز به داشتن Check Point تا مرحله ای خاص وجود دارد.
اگر به خاطر داشته باشید در الگوی Command نیز اشاره شد که این الگو برای پیاده سازی عملیات Undo و Redo می تواند استفاده شود. اما تفاوت این دو الگو در چیست؟
نکته کلیدی که در این الگو وجود دارد این است که ذخیره وضعیت یک شی کاملا متفاوت از شی می باشد و استفاده کننده از این الگو به هیچ عنوان به یادداشت ها دسترسی ندارد بلکه دسترسی به یادداشت ها فقط برای ایجاد کننده یادداشت ها امکان پذیر است.
همان طور که در دیاگرام مشخص است نمودار کلاس الگوی Memento شامل کلاس های زیر است:
همچنین این الگو دارای دو واسط می باشد:
در ادامه، پیاده سازی این الگو را در یک مثال توضیح می دهیم:
فرض کنید در یک صفحه وب یک فیلد متنی دارید که می خواهید عملیات ذخیره و Undo و Redo را برای متن تایپ شده در این فیلد پیاده سازی نمایید، به صورتی که با کلیک بر روی کلید Undo متن تایپ شده رد فیلد به مقدار قبلی که ذخیره شده بود برگردانده شود و برعکس با کلیک بر روی کلید Redo به متن بعدی برگردانده شود. با استفاده از الگوی Memento پیاده سازی به صورت زیر خواهد بود:
کلاس ایجاد کننده که در آن وضعیت و عملیات مورد استفاده به صورت زیر تعریف می شود:
public class Originator
{
private string article;
public void set(string newArticle)
{
var message = String.Format("From Originator: Current Version of Article {0}",newArticle);
article = newArticle;
}
public Memento storeInMemento()
{
var message = String.Format("From Originator: Saving to Memento");
return new Memento(article);
}
public string restoreFromMemento(Memento memento)
{
article = memento.getSavedArticle();
var message = String.Format("From Originator: Previous Article Saved in Memento");
return article;
}
}
کلاس یادداشت ها که وضعیت را نگهداری نموده و آن را بازیابی می نماید و به صورت زیر پیاده سازی می شود:
public class Memento
{
private string article;
public Memento(string articleSaved)
{
article = articleSaved;
}
public string getSavedArticle()
{
return article;
}
}
کلاس سرپرست که لیستی از وضعیت ها را نگهداری می نماید و به این ترتیب وضعیت در مراحل مختلف قابل دسترسی خواهد بود:
public class Caretaker
{
List savedArticles = new List();
public void addMemento(Memento m)
{
savedArticles.Add(m);
}
public Memento getMemento(int index)
{
return savedArticles[index];
}
}
در صفحه مورد نظر نیز باید متغییرهایی از کلاس های فوق به صورت زیر ایجاد نمود:
static Caretaker caretaker = new Caretaker();
static Originator originator = new Originator();
static int saveFiles = 0, currentArticlce = 0;
سپس رخدادهای مربوط به هر کدام از کلیدهای موجود در صفحه را به صورت زیر پیاده سازی می نماییم:
protected void btnSaveListener_Click(object sender, EventArgs e)
{
originator.set(txtArticle.Text);
caretaker.addMemento(originator.storeInMemento());
saveFiles++;
currentArticlce++;
}
protected void btnUndoListener_Click(object sender, EventArgs e)
{
if (currentArticlce >= 1)
{
currentArticlce--;
string txtString = originator.restoreFromMemento(caretaker.getMemento(currentArticlce));
txtArticle.Text = txtString;
btnRedoListener.Enabled = true;
}
else
{
btnUndoListener.Enabled = false;
}
}
protected void btnRedoListener_Click(object sender, EventArgs e)
{
if(saveFiles-1>currentArticlce)
{
currentArticlce++;
string txtString = originator.restoreFromMemento(caretaker.getMemento(currentArticlce));
txtArticle.Text = txtString;
btnUndoListener.Enabled = true;
}
else
{
btnRedoListener.Enabled = false;
}
}
3,289بازدید
دیدگاه کاربران
هنوز دیدگاهی ثبت نشده است.
شما میتوانید درباره این مقاله، دیدگاه خود را ثبت کنید.