อ่าน 4 นาที
รูปแบบตัววนซ้ำ
ใน การเขียนโปรแกรมเชิงวัตถุ รูปแบบตัววนซ้ำ (Iterator Pattern) เป็นรูป แบบการออกแบบ ที่ใช้ ตัววนซ้ำ ในการวนไปรอบๆ คอนเทนเนอร์ และเข้าถึงองค์ประกอบต่างๆ ของคอนเทนเนอร์...
รูปแบบตัววนซ้ำ
ในการเขียนโปรแกรมเชิงวัตถุรูปแบบตัววนซ้ำ (Iterator Pattern)เป็นรูปแบบการออกแบบที่ใช้ตัววนซ้ำ ในการวนไปรอบๆ คอนเทนเนอร์และเข้าถึงองค์ประกอบต่างๆ ของคอนเทนเนอร์ รูปแบบตัววนซ้ำช่วยแยกอัลกอริทึม ออก จากคอนเทนเนอร์ ในบางกรณี อัลกอริทึมมีความเฉพาะเจาะจงกับคอนเทนเนอร์และไม่สามารถแยกออกจากกันได้
ตัวอย่างเช่น อัลกอริทึมสมมุติsearchForElement()สามารถนำไปใช้ได้โดยทั่วไปโดยใช้ตัววนซ้ำประเภทที่กำหนดไว้ แทนที่จะนำไปใช้เป็นอัลกอริทึมเฉพาะสำหรับคอนเทนเนอร์ วิธีนี้ทำให้สามารถsearchForElement()ใช้งานได้กับคอนเทนเนอร์ใดๆ ที่รองรับตัววนซ้ำประเภทที่ต้องการ
ภาพรวม
รูปแบบการออกแบบ Iterator [ 1 ] เป็นหนึ่งใน 23 รูปแบบการออกแบบ "Gang of Four" ที่รู้จักกันดี ซึ่งอธิบายวิธีการแก้ปัญหาการออกแบบที่เกิดขึ้นซ้ำๆ เพื่อออกแบบซอฟต์แวร์เชิงวัตถุที่มีความยืดหยุ่นและนำกลับมาใช้ใหม่ได้ กล่าวคือ วัตถุที่ง่ายต่อการใช้งาน เปลี่ยนแปลง ทดสอบ และนำกลับมาใช้ใหม่
รูปแบบการออกแบบ Iterator สามารถแก้ปัญหาอะไรได้บ้าง?
- องค์ประกอบของวัตถุรวมควรสามารถเข้าถึงได้และสำรวจโดยไม่ต้องเปิดเผยรูปแบบการแสดงผล (โครงสร้างข้อมูล) ของวัตถุนั้น
- ควรมีการกำหนดการดำเนินการสำรวจใหม่สำหรับวัตถุรวมโดยไม่ต้องเปลี่ยนแปลงอินเทอร์เฟซของวัตถุนั้น
การกำหนดการเข้าถึงและการดำเนินการสำรวจในอินเทอร์เฟซของ Aggregate นั้นไม่ยืดหยุ่น เนื่องจากเป็นการผูกมัด Aggregate กับการเข้าถึงและการดำเนินการสำรวจแบบเฉพาะเจาะจง และทำให้ไม่สามารถเพิ่มการดำเนินการใหม่ในภายหลังได้โดยไม่ต้องเปลี่ยนแปลงอินเทอร์เฟซของ Aggregate
รูปแบบการออกแบบ Iterator อธิบายถึงวิธีการแก้ปัญหาแบบใด?
- กำหนดอ็อบเจ็กต์แยกต่างหาก (ตัววนซ้ำ) ที่ห่อหุ้มการเข้าถึงและการวนดูอ็อบเจ็กต์รวม
- ไคลเอ็นต์ใช้ตัววนซ้ำเพื่อเข้าถึงและสำรวจข้อมูลรวมโดยไม่ทราบรูปแบบการแสดงผล (โครงสร้างข้อมูล) ของข้อมูลนั้น
สามารถใช้ตัววนซ้ำที่แตกต่างกันเพื่อเข้าถึงและสำรวจข้อมูลรวมในรูปแบบต่างๆ ได้ การดำเนินการเข้าถึงและสำรวจใหม่สามารถกำหนดได้อย่างอิสระโดยการกำหนดตัววนซ้ำใหม่
โปรดดูแผนภาพคลาสและลำดับ UML ด้านล่างด้วย
คำนิยาม
สาระสำคัญของรูปแบบ Iterator คือ "การจัดหาวิธีเข้าถึงองค์ประกอบของวัตถุรวมตามลำดับโดยไม่ต้องเปิดเผยการแสดงผลพื้นฐาน" [ 3 ]
โครงสร้าง
แผนภาพคลาสและลำดับ UML

ในแผนภาพคลาสUML ข้างต้น คลาสอ้างอิงถึง (1) อินเทอร์เฟซสำหรับการสร้างวัตถุ ( ) และ (2) อินเทอร์เฟซสำหรับการเข้าถึงวัตถุ ( , ) คลาสใช้งานอินเทอร์เฟซโดยการเข้าถึงคลาส ClientAggregateIteratorcreateIterator()IteratorAggregatenext()hasNext()Iterator1IteratorAggregate1
แผนภาพลำดับUML แสดงปฏิสัมพันธ์ขณะรันไทม์: อ็อบเจ็กต์หนึ่งเรียกใช้เมธอดของอ็อบเจ็กต์อีกตัวหนึ่ง ซึ่งจะสร้างอ็อบเจ็กต์อีกตัวหนึ่งและส่งกลับไปยังอ็อบเจ็กต์หลัก จากนั้น อ็อบเจ็กต์หลักจะใช้เมธอดเพื่อวนดูองค์ประกอบต่างๆ ของอ็อบเจ็กต์ นั้นClientcreateIterator()Aggregate1Iterator1ClientClientIterator1Aggregate1
แผนภาพคลาส UML

ตัวอย่าง
บางภาษาได้กำหนดมาตรฐานไวยากรณ์ไว้แล้ว ภาษา C++ และ Python เป็นตัวอย่างที่เห็นได้ชัด
ซี++
ภาษา C++ใช้หลักการทำงานแบบเดียวกับตัวชี้ (pointer) ในการสร้างตัววน ซ้ำ (iterator) ใน C++ คลาสสามารถโอเวอร์โหลดการทำงานของตัวชี้ได้ทั้งหมด ดังนั้นจึงสามารถสร้างตัววนซ้ำที่ทำงานได้เหมือนตัวชี้ โดยมีฟังก์ชันการเข้าถึงค่าที่ตัวชี้ชี้ (dereference), การเพิ่มค่า (increment) และการลดค่า (decrement) ข้อดีคือ อัลกอริทึมใน C++ std::sortสามารถนำไปใช้กับบัฟเฟอร์หน่วยความจำแบบเดิมได้ทันที และไม่ต้องเรียนรู้ไวยากรณ์ใหม่ อย่างไรก็ตาม มันต้องใช้ตัววนซ้ำ "สิ้นสุด" (end iterator) เพื่อทดสอบความเท่าเทียมกัน แทนที่จะปล่อยให้ตัววนซ้ำรู้เองว่าถึงจุดสิ้นสุดแล้ว ในภาษา C++ เรากล่าวว่าตัววนซ้ำจำลองแนวคิดของตัววนซ้ำ (iterator concept )
การใช้งาน C++23 นี้อิงตามบท "การขยายเวกเตอร์อีกครั้ง" [ 5 ]
import std ;template < typename T > using InitializerList = std :: initializer_list < T > ; using OutOfRangeException = std :: out_of_range ; template < typename T > using UniquePtr = std :: unique_ptr < T > ;class DoubleVector { private : UniquePtr < double [] > elements ; size_t listSize ; public : using Iterator = double * ;[[ nodiscard ]] Iterator begin () const noexcept { return elements ; }[[ nodiscard ]] Iterator end () const noexcept { return elements + listSize ; } DoubleVector ( InitializerList < double > list ) : elements { std :: make_unique < double [] > ( list . size ())}, listSize { list . size ()} { double * p = elements ; for ( auto i = list . begin (); i != list . end (); ++ i , ++ p ) { * p = * i ; } // alternatively implemented with // std::ranges::copy(list, elements.get()) }~ DoubleVector () = default ;[[ nodiscard ]] size_t size () const noexcept { return listSize ; }[[ nodiscard ]] double & operator []( size_t n ) { if ( n >= listSize ) { throw OutOfRangeException ( "DoubleVector::operator[] เกินขอบเขต!" ); } return elements [ n ]; }DoubleVector ( const DoubleVector & ) = delete ; // ปิดใช้งานการสร้างสำเนาDoubleVector & operator = ( const DoubleVector & ) = delete ; // ปิดใช้งานการกำหนดค่าสำเนา};int main ( int argc , char * argv []) { DoubleVector v = { 1.1 * 1.1 , 2.2 * 2.2 }; for ( const double & x : v ) { std :: println ( "{}" , x ); } for ( size_t i = v . begin (); i != v . end (); ++ i ) { std :: println ( "{}" , * i ); } for ( size_t i = 0 ; i <= v . size (); ++ i ) { std :: println ( "{}" , v [ i ]); } }ผลลัพธ์ของโปรแกรมคือ
1.21 4.84 1.21 4.84 1.21 4.84 terminate called after throwing an instance of ' OutOfRangeException ' what () : DoubleVector :: operator [] out of range !ดูเพิ่มเติม
ลิงก์ภายนอก
- การวนซ้ำอ็อบเจ็กต์ใน PHP
- รูปแบบ Iteratorใน C#
- รูปแบบตัววนซ้ำใน UML และใน LePUS3 (ภาษาสร้างแบบจำลองเชิงทางการ)
- บทช่วยสอนการสร้างซอร์สโค้ด
- บทช่วยสอนตัวอย่างการใช้งาน Design Patterns
- รูปแบบตัววนซ้ำ
สรุปเนื้อหา
ข้อมูลสำคัญจากบทความ
ข้อมูลสำคัญเกี่ยวกับ รูปแบบตัววนซ้ำ
ใน การเขียนโปรแกรมเชิงวัตถุ รูปแบบตัววนซ้ำ (Iterator Pattern) เป็นรูป แบบการออกแบบ ที่ใช้ ตัววนซ้ำ ในการวนไปรอบๆ คอนเทนเนอร์ และเข้าถึงองค์ประกอบต่างๆ ของคอนเทนเนอร์...
ภาพรวม
รูปแบบการออกแบบ Iterator [ 1 ] เป็นหนึ่งใน 23 รูปแบบการออกแบบ "Gang of Four" ที่รู้จักกันดี ซึ่งอธิบายวิธีการแก้ปัญหาการออกแบบที่เกิดขึ้นซ้ำๆ เพื่อออกแบบซอฟต์แวร์เชิงวัตถุที่มีความยืดหยุ่นและนำกลับมาใช้ใหม่ได้ กล่าวคือ วัตถุที่ง่ายต่อการใช้งาน เปลี่ยนแปลง...
รูปแบบการออกแบบ Iterator อธิบายถึงวิธีการแก้ปัญหาแบบใด?
สามารถใช้ตัววนซ้ำที่แตกต่างกันเพื่อเข้าถึงและสำรวจข้อมูลรวมในรูปแบบต่างๆ ได้ การดำเนินการเข้าถึงและสำรวจใหม่สามารถกำหนดได้อย่างอิสระโดยการกำหนดตัววนซ้ำใหม่
คำนิยาม
สาระสำคัญของรูปแบบ Iterator คือ "การจัดหาวิธีเข้าถึงองค์ประกอบของวัตถุรวมตามลำดับโดยไม่ต้องเปิดเผยการแสดงผลพื้นฐาน" [ 3 ]