3.5. Memento¶
3.5.1. تعریف¶
دیزاین پترن Memento یک الگوی رفتاری محسوب میشه که امکان ذخیره و بازگردانی وضعیت قبل یک آبجکت رو به برنامه اضافه می کنه بدون اینکه سطح بالای برنامه از نحوه پیاده سازی این الگو اطلاعی داشته باشه.
در واقع این الگو امکان undo و redo رو به برنامه اضافه می کنه.
3.5.2. چه زمانی استفاده میشه؟¶
این الگو رو زمانی در برنامه استفاده می کنیم که نیاز به ذخیره کردن یک حالت خاص از برنامه و برگشت به اون حالت در زمان دیگه داشته باشیم.
3.5.3. اجزاء¶
الگوی طراحی Memento از چند بخش اصلی تشکیل میشه:
بخش اول این الگو Originator هست که وضعیت یا State اون می بایست ذخیره بشه.
بعد از اون Memento رو داریم که وضعیت Originator رو ذخیره می کنه.
و در نهایت هم Caretaker رو داریم که مسئول مدیریت آبجکت Memento و تاریخچه ی تغییر وضعیت های Originator هست.
Vanderjoe, CC BY-SA 4.0, via Wikimedia Commons
Caution
✅ مزایای استفاده
امکان ذخیره سازی وضعیت آبجکت و برگشتن به آن در زمان مورد نظر
Warning
❌ معایب استفاده
امکان مصرف بالای رم
زبان های برنامه نویسی داینامیک مثل PHP نمیتونن تضمین کنن که وضعیت ذخیره شده در Memento دست نخورده باقی میمونه
3.5.4. کاربرد عملی¶
این الگو در زبان PHP کاربرد خیلی زیادی نداره و معمولا کاربرد اون در این زبان زیر سوال هست تا حدودی! چون در اکثر اوقات ایجاد یک کپی از آبجکت با serialize کردن اون ساده تر هست!
بریم سراغ پیاده سازی عملی این الگو در PHP8 که مربوط میشه به یک Editor با قابلیت برگشت به وضعیت قبل
3.5.5. پیاده سازی¶
ابتدا کلاس Editor که همون Originator ما هست رو تعریف می کنیم:
1<?php
2
3// Originator class
4class Editor
5{
6 private string $content;
7
8 public function __construct()
9 {
10 $this->content = '';
11 }
12
13 public function type(string $words): void
14 {
15 $this->content .= ' ' . $words;
16 }
17
18 public function getContent(): string
19 {
20 return $this->content;
21 }
22
23 public function save(): EditorMemento
24 {
25 return new EditorMemento($this->content);
26 }
27
28 public function restore(EditorMemento $memento): void
29 {
30 $this->content = $memento->getContent();
31 }
32}
بعد از اون کلاس Memento رو داریم:
1<?php
2
3// Memento class
4class EditorMemento
5{
6 private string $content;
7
8 public function __construct(string $content)
9 {
10 $this->content = $content;
11 }
12
13 public function getContent(): string
14 {
15 return $this->content;
16 }
17}
و در نهایت Caretaker:
1<?php
2
3// Caretaker class
4class EditorHistory
5{
6 private array $mementos = [];
7
8 public function addMemento(EditorMemento $memento): void
9 {
10 $this->mementos[] = $memento;
11 }
12
13 public function getMemento(int $index): EditorMemento
14 {
15 return $this->mementos[$index];
16 }
17}
3.5.6. نحوه فراخوانی¶
1<?php
2
3// Usage example
4$editor = new Editor();
5$editor->type('This is the first sentence.');
6$editor->type('This is the second sentence.');
7
8// Save the current state
9$history = new EditorHistory();
10$history->addMemento($editor->save());
11
12// Add more content
13$editor->type('This is the third sentence.');
14
15// Restore to previous state
16$editor->restore($history->getMemento(0));
17
18echo $editor->getContent(); // Output: This is the first sentence. This is the second sentence.
به همین سادگی!