1. الگوی Memento چیست

الگوی Memento یک الگوی طراحی رفتاری است که برای ذخیره وبازیابی وضعیت داخلی یک شیء استفاده می‌شود. این الگو وضعیت شیء را در یک شیء memento ذخیره می‌کند که می‌توان از آن برای بازیابی وضعیت قبلی شیء در آینده استفاده نمود.

2. ویژگی‌ها و مزایای الگوی Memento

ویژگی‌ها و مزایای الگوی Memento عبارتند از:

  • قابلیت ذخیره وبازیابی وضعیت داخلی یک شیء بدون نقض اصل کپسوله‌سازی.
  • قابلیت مدیریت انعطاف‌پذیر وضعیت‌های تاریخی یک شیء، که تسهیل انجام عملیات undo و redo را فراهم می‌کند.
  • امکان ذخیره وضعیت به صورت خارجی، جلوگیری از انتشار وضعیت داخلی شیء.

3. مثال‌های کاربردی الگوی Memento

الگوی Memento دارای بسیاری از برنامه‌های عملیاتی است که برخی از مثال‌های آن عبارتند از:

  • قابلیت undo و redo در ویرایشگرهای متن که می‌توانند از الگوی Memento برای ذخیره وضعیت هر عملیات استفاده نمایند.
  • قابلیت ذخیره وبارگذاری در بازی‌ها که می‌توانند از الگوی Memento برای ذخیره پیشرفت بازی استفاده کنند.
  • قابلیت ذخیره پیش‌نویس در مشتریان ایمیل که می‌توانند از الگوی Memento برای ذخیره وضعیت پیش‌نویس ایمیل استفاده کنند.

4. پیاده‌سازی الگوی Memento در Golang

4.1. نمودار کلاس UML

الگوی Memento در Golang

4.2. معرفی مثال

توضیح براساس نمودار کلاس UML

در این مثال، ما یک کلاس Originator با یک وضعیت داخلی به نام "state" داریم. Originator با استفاده از متد SetState وضعیت را تنظیم می‌کند و با استفاده از متد CreateMemento یک شیء memento ایجاد می‌کند. وضعیت داخلی شیء مemento دقیقاً مانند Originator است. کلاس Caretaker مسئول ذخیره شیء memento و اضافه کردن mementos با استفاده از متد AddMemento می‌باشد.

مراحل پیاده‌سازی

  1. ایجاد شیء Memento که دارای متد GetState برای ذخیره وضعیت داخلی Originator است.
  2. ایجاد شیء Originator که دارای متدهای تنظیم وضعیت و ایجاد memento است.
  3. ایجاد شیء Caretaker که مسئول ذخیره شیء memento می‌باشد.
  4. پیاده‌سازی متدها برای ایجاد یک memento و بازنشانی وضعیت در Originator:
    • هنگام ایجاد یک شیء memento، وضعیت Originator را در memento ذخیره نمایید.
    • هنگام بازنشانی وضعیت، وضعیت را از memento به Originator بازیابی نمایید.
  5. پیاده‌سازی متدهای اضافه کردن یک memento و گرفتن memento در Caretaker:
    • متد اضافه کردن memento برای ذخیره شیء memento در Caretaker استفاده می‌شود.
    • متد گرفتن memento برای بازیابی شیء memento از Caretaker استفاده می‌شود.

4.3.1. ایجاد یک شیء Memento

type Memento struct {
	state string
}

func (m *Memento) GetState() string {
	return m.state
}

4.3.2. ذخیره وضعیت در شیء Memento

type Originator struct {
	state string
}

func (o *Originator) SetState(state string) {
	o.state = state
}

func (o *Originator) CreateMemento() *Memento {
	return &Memento{state: o.state}
}

4.3.3. بازیابی وضعیت از شیء Memento

func (o *Originator) SetMemento(memento *Memento) {
	o.state = memento.GetState()
}

4.3.4. استفاده از الگوی Memento برای عملیات undo

type Caretaker struct {
	mementos []*Memento
}

func (c *Caretaker) AddMemento(m *Memento) {
	c.mementos = append(c.mementos, m)
}

func (c *Caretaker) GetMemento(index int) *Memento {
	return c.mementos[index]
}

4.3.5. استفاده از الگوی Memento برای عملیات بازگشتی

func main() {
	originator := &Originator{}
	caretaker := &Caretaker{}

	originator.SetState("وضعیت 1")
	caretaker.AddMemento(originator.CreateMemento())

	originator.SetState("وضعیت 2")
	caretaker.AddMemento(originator.CreateMemento())

	originator.SetMemento(caretaker.GetMemento(0))
	fmt.Println("وضعیت اصلی پس از بازگردانی به وضعیت 1:", originator.state)

	originator.SetMemento(caretaker.GetMemento(1))
	fmt.Println("وضعیت اصلی پس از بازگردانی به وضعیت 2:", originator.state)
}