ในความคิดของฉัน UNDO / REDO สามารถใช้งานได้ 2 วิธีในวงกว้าง 1. ระดับคำสั่ง (เรียกว่าระดับคำสั่ง Undo / Redo) 2. ระดับเอกสาร (เรียกว่า Global Undo / Redo)
ระดับคำสั่ง: ตามที่หลาย ๆ คำตอบชี้ให้เห็นสิ่งนี้ทำได้อย่างมีประสิทธิภาพโดยใช้รูปแบบ Memento หากคำสั่งยังสนับสนุนการทำเจอร์นัลการดำเนินการด้วยจะรองรับการทำซ้ำได้อย่างง่ายดาย
ข้อ จำกัด : เมื่อขอบเขตของคำสั่งหมดการเลิกทำ / ทำซ้ำจะเป็นไปไม่ได้ซึ่งจะนำไปสู่ระดับเอกสาร (ทั่วโลก) เลิกทำ / ทำซ้ำ
ฉันเดาว่ากรณีของคุณจะเข้ากับการเลิกทำ / ทำซ้ำทั่วโลกเนื่องจากเหมาะสำหรับรุ่นที่มีพื้นที่หน่วยความจำจำนวนมาก นอกจากนี้ยังเหมาะสำหรับการเลือกเลิกทำ / ทำซ้ำด้วย มีสองประเภทดั้งเดิม
- หน่วยความจำทั้งหมดเลิกทำ / ทำซ้ำ
- ระดับวัตถุเลิกทำซ้ำ
ใน "ยกเลิก / ทำซ้ำหน่วยความจำทั้งหมด" หน่วยความจำทั้งหมดจะถือว่าเป็นข้อมูลที่เชื่อมต่อกัน (เช่นต้นไม้หรือรายการหรือกราฟ) และหน่วยความจำได้รับการจัดการโดยแอปพลิเคชันแทนที่จะเป็นระบบปฏิบัติการ ดังนั้นตัวดำเนินการใหม่และลบหากใน C ++ มีมากเกินไปเพื่อให้มีโครงสร้างที่เฉพาะเจาะจงมากขึ้นเพื่อใช้การดำเนินการอย่างมีประสิทธิภาพเช่น a. ถ้าโหนดใด ๆ ถูกแก้ไข b. การเก็บและล้างข้อมูลเป็นต้นวิธีการทำงานโดยทั่วไปคือการคัดลอกหน่วยความจำทั้งหมด (สมมติว่าการจัดสรรหน่วยความจำได้รับการปรับให้เหมาะสมแล้วและจัดการโดยแอปพลิเคชันโดยใช้อัลกอริทึมขั้นสูง) และจัดเก็บไว้ในกองซ้อน หากมีการร้องขอสำเนาของหน่วยความจำโครงสร้างทรีจะถูกคัดลอกตามความจำเป็นในการคัดลอกแบบตื้นหรือแบบลึก สำเนาแบบลึกถูกสร้างขึ้นเฉพาะสำหรับตัวแปรที่แก้ไข เนื่องจากทุกตัวแปรถูกจัดสรรโดยใช้การจัดสรรแบบกำหนดเอง แอปพลิเคชันมีคำพูดสุดท้ายว่าจะลบเมื่อใดหากจำเป็น สิ่งที่น่าสนใจมากถ้าเราต้องแบ่งพาร์ติชัน Undo / Redo เมื่อมันเกิดขึ้นเราจำเป็นต้องเลือก Undo / Redo ชุดการทำงานที่เลือกโดยโปรแกรม ในกรณีนี้เฉพาะตัวแปรใหม่เหล่านั้นหรือตัวแปรที่ถูกลบหรือตัวแปรที่แก้ไขแล้วเท่านั้นที่จะได้รับแฟล็กเพื่อให้ Undo / Redo ยกเลิก / ทำซ้ำหน่วยความจำเหล่านั้นเท่านั้นสิ่งที่น่าสนใจยิ่งขึ้นหากเราจำเป็นต้องทำการ Undo / Redo บางส่วนภายในออบเจ็กต์ เมื่อเป็นเช่นนี้จึงมีการใช้แนวคิด "รูปแบบผู้เยี่ยมชม" ที่ใหม่กว่า เรียกว่า "Object Level Undo / redo" หรือตัวแปรที่ถูกลบหรือตัวแปรที่แก้ไขจะได้รับแฟล็กเพื่อให้ Undo / Redo เท่านั้นเลิกทำ / ทำซ้ำหน่วยความจำเหล่านั้นสิ่งต่างๆจะน่าสนใจยิ่งขึ้นหากเราจำเป็นต้องทำการ Undo / Redo บางส่วนภายในออบเจ็กต์ เมื่อเป็นเช่นนี้จึงมีการใช้แนวคิด "รูปแบบผู้เยี่ยมชม" ที่ใหม่กว่า เรียกว่า "Object Level Undo / redo" หรือตัวแปรที่ถูกลบหรือตัวแปรที่แก้ไขจะได้รับแฟล็กเพื่อให้ Undo / Redo เท่านั้นเลิกทำ / ทำซ้ำหน่วยความจำเหล่านั้นสิ่งต่างๆจะน่าสนใจยิ่งขึ้นหากเราจำเป็นต้องทำการ Undo / Redo บางส่วนภายในออบเจ็กต์ เมื่อเป็นเช่นนี้จึงมีการใช้แนวคิด "รูปแบบผู้เยี่ยมชม" ที่ใหม่กว่า เรียกว่า "Object Level Undo / redo"
- ระดับออบเจ็กต์เลิกทำ / ทำซ้ำ: เมื่อมีการเรียกการแจ้งเตือนให้เลิกทำ / ทำซ้ำทุกออบเจ็กต์จะดำเนินการสตรีมมิ่งซึ่งสตรีมเมอร์จะได้รับข้อมูลเก่า / ข้อมูลใหม่จากอ็อบเจ็กต์ที่ตั้งโปรแกรมไว้ ข้อมูลที่ไม่ถูกรบกวนจะไม่ถูกรบกวน ทุกออบเจ็กต์ได้รับสตรีมเมอร์เป็นอาร์กิวเมนต์และภายในการเรียก UNDo / Redo จะสตรีม / ยกเลิกการสตรีมข้อมูลของวัตถุ
ทั้ง 1 และ 2 อาจมีวิธีการเช่น 1. BeforeUndo () 2. AfterUndo () 3. BeforeRedo () 4. AfterRedo () ต้องเผยแพร่วิธีการเหล่านี้ในคำสั่ง Undo / redo พื้นฐาน (ไม่ใช่คำสั่งตามบริบท) เพื่อให้อ็อบเจ็กต์ทั้งหมดใช้เมธอดเหล่านี้ด้วยเพื่อให้ได้การดำเนินการเฉพาะ
กลยุทธ์ที่ดีคือการสร้างลูกผสมของ 1 และ 2 ความสวยงามก็คือวิธีการเหล่านี้ (1 & 2) เองใช้รูปแบบคำสั่ง