ฉันสงสัยว่ามันคืออะไรที่ทำให้ Iterator เป็นพิเศษเมื่อเทียบกับสิ่งก่อสร้างที่คล้ายกันอื่น ๆ และทำให้Gang of Fourแสดงว่าเป็นรูปแบบการออกแบบ
Iterator ขึ้นอยู่กับความแตกต่าง (ลำดับชั้นของคอลเลกชันที่มีอินเตอร์เฟซทั่วไป) และการแยกข้อกังวล (การวนซ้ำในการรวบรวมควรเป็นอิสระจากวิธีการจัดโครงสร้างข้อมูล)
แต่จะเกิดอะไรขึ้นถ้าเราแทนที่ลำดับชั้นของคอลเลกชันด้วยเช่นลำดับชั้นของวัตถุทางคณิตศาสตร์ (จำนวนเต็ม, ลอย, ซับซ้อน, เมทริกซ์ ฯลฯ ) และตัววนซ้ำโดยคลาสที่แสดงถึงการดำเนินการบางอย่างที่เกี่ยวข้องกับวัตถุเหล่านี้ แผนภาพคลาสจะเหมือนกัน
เราอาจพบตัวอย่างที่คล้ายกันอื่น ๆ อีกมากมายเช่น Writer, Painter, Encoder และคนที่ดีกว่าซึ่งทำงานในลักษณะเดียวกัน อย่างไรก็ตามฉันไม่เคยได้ยินชื่อเหล่านี้เรียกว่ารูปแบบการออกแบบ
แล้วอะไรที่ทำให้ Iterator มีความพิเศษ?
ความจริงที่ว่ามันซับซ้อนกว่าเพราะต้องมีสถานะที่ไม่แน่นอนในการจัดเก็บตำแหน่งปัจจุบันภายในคอลเลกชันหรือไม่? แต่แล้วรัฐที่ไม่แน่นอนมักจะไม่ได้รับการพิจารณาว่าเป็นที่น่าพอใจ
เพื่อชี้แจงประเด็นของฉันให้ฉันยกตัวอย่างรายละเอียดเพิ่มเติม
นี่คือปัญหาการออกแบบของเรา:
สมมติว่าเรามีลำดับชั้นของชั้นเรียนและการดำเนินการที่กำหนดไว้ในวัตถุของชั้นเรียนเหล่านี้ อินเทอร์เฟซของการดำเนินการนี้จะเหมือนกันสำหรับแต่ละคลาส แต่การใช้งานอาจแตกต่างกันโดยสิ้นเชิง นอกจากนี้ยังสันนิษฐานว่ามันสมเหตุสมผลที่จะใช้การดำเนินการหลายครั้งบนวัตถุเดียวกันพูดด้วยพารามิเตอร์ที่แตกต่างกัน
นี่คือทางออกที่สมเหตุสมผลสำหรับปัญหาการออกแบบของเรา (ในทางปฏิบัติทั่วไปของรูปแบบตัววนซ้ำ):
สำหรับการแยกความกังวลการใช้งานของการดำเนินการไม่ควรเพิ่มเป็นฟังก์ชั่นไปยังลำดับชั้นของระดับเดิม (วัตถุตัวถูกดำเนินการ) เนื่องจากเราต้องการที่จะใช้การดำเนินการหลายครั้งในตัวถูกดำเนินการเดียวกันมันควรจะเป็นตัวแทนของวัตถุที่มีการอ้างอิงถึงตัวถูกดำเนินการไม่เพียงแค่ฟังก์ชั่น ดังนั้นวัตถุตัวถูกดำเนินการควรให้ฟังก์ชั่นที่ส่งกลับวัตถุที่เป็นตัวแทนของการดำเนินการ วัตถุนี้มีฟังก์ชั่นที่ดำเนินการตามจริง
ตัวอย่าง:
มีชั้นฐานหรืออินเตอร์เฟซที่เป็นMathObject
(ชื่อโง่ฉันรู้ว่าอาจจะมีคนที่มีความคิดที่ดี.) กับการเรียนมาและMyInteger
MyMatrix
สำหรับMathObject
การดำเนินการแต่ละครั้งPower
ควรมีการกำหนดที่อนุญาตให้คำนวณสแควร์คิวบ์และอื่น ๆ ดังนั้นเราสามารถเขียน (ใน Java):
MathObject i = new MyInteger(5);
Power powerOfFive = i.getPower();
MyInteger square = powerOfFive.calculate(2); // should return 25
MyInteger cube = powerOfFive.calculate(3); // should return 125