Saladpuk.com
🏆 เนื้อหาหลัก
🏆 เนื้อหาหลัก
  • 💖สลัดผัก
  • 📰มีอะไรใหม่บ้าง
    • 2020
      • 2020-11
      • 2020-10
      • 2020-09
      • 2020-08
      • 2020-03
      • 2020-02
      • 2020-01
    • 2019
      • 2019-12
      • 2019-11
      • 2019-10
      • 2019-09
      • 2019-08
  • 🤔อ่านเรื่องไรดี ?
  • มือใหม่หัดเขียนโค้ด
    • 👶เขียนโค้ดด้วยภาษา C#
      • เกิดมาไม่เคยเขียนโค้ดมาก่อนเบย
      • 👶พื้นฐาน
        • 1.โปรแกรมที่ต้องลง
        • 2.โครงสร้างของโค้ด
        • 3.ชนิดของข้อมูล
        • 4.การสร้างตัวแปร
        • 5.คำสั่งพื้นฐาน
        • 6.การแปลงข้อมูล
        • 7.การเปรียบเทียบค่า
        • 8.การตัดสินใจด้วย IF statements
        • 9.การตัดสินใจด้วย Switch statements
        • 10.การทำงานซ้ำๆด้วย While
        • 11.การทำงานซ้ำๆด้วย Do While
        • 12.การทำงานซ้ำๆด้วย For
        • 13.การแก้โจทย์จากรูป
        • 14.มารู้จักกับ Array กัน
      • 🧑ระดับกลาง
        • 15.Value type vs Reference type
        • 16.ลดงานซ้ำๆด้วย Method
        • 17.มารู้จักกับ Class & Field กัน
        • 18.มารู้จักกับ Constructor กันบ้าง
        • 19.มาเขียน Method ใน Class กัน
        • 20.มารู้จักกับ Property กัน
        • 21.ลองใช้คลาสแบบจริงจังบ้าง
        • 22.การสืบทอด Inheritance
        • 23.Polymorphism
        • 24.Abstract Class
        • 25.Interface
        • 26.Namespace
        • 27.Enum
        • 28.Exception handler
        • 29.ลงลึกกับ string
        • 30.StringBuilder เพื่อนคู่ string
      • 👨⏳ระดับสูง
        • Generic
        • Delegates
        • Action & Func
        • Lambda expression
        • LINQ
        • พระคัมภีร์การใช้คำสั่ง LINQ
      • 💡Tips
        • 💡C# version 8.0
        • 💡Boxing & Unboxing
    • 👶Algorithm
      • 👾Algorithm Big-O
      • 👽Algorithm P & NP
    • 👦OOP
      • 💖Abstraction
      • 💖Encapsulation
      • 🏆Abstraction & Encapsulation
      • 💖Inheritance
      • 💖Polymorphism
      • 🏆Inheritance & Polymorphism
      • 📝ลองเขียน OOP ดูดิ๊
      • 👑OOP + Power of Design
      • 🥰เทคนิคในการออกแบบ
    • 👶บทสรุปฐานข้อมูล
      • เก็บรูปในฐานข้อมูล
      • Database indexing
      • การลบข้อมูล
    • 👦Communication Patterns
    • 👦Design Patterns
      • 🤰Creational Patterns
        • 🏭Factory Method
        • 🏭Abstract Factory
        • ☝️ Singleton Pattern
        • 🏗️ Builder Pattern
        • 🎎Prototype Pattern
      • 🧱Structural Patterns
        • 🔌Adapter Pattern
        • 📪Proxy Pattern
  • Puzzle
    • 🧠Challenges
      • 🐴Google ม้า 25 ตัว
      • 🌉Amazon เสา 2 ต้น
      • 🥇ทองเก๊
      • 💊ยาต้านโควิด
      • 🎩CP หมวก 5 ใบ
      • 🧓Einstein's Riddle 01
  • พื้นฐานที่ควรต้องรู้
    • 🐳Docker
      • 📦Docker Containers
      • 🃏Docker Exercise 01
      • 🛠️ Docker Tools
      • 🗃️ Docker Registry
      • 🖼️ Container Image
      • 📢Docker Push
      • 🔄WSL
    • 👶Clean Code
      • 🧓Uncle Bob - Clean Code
      • 🧓Uncle Bob - Comments
      • 🧓Uncle Bob - Naming
      • 🧓Uncle Bob - Mindset
      • 🧓Uncle Bob - TDD
    • 👶Code Smells
    • 👶สิ่งที่คนเขียนโค้ดมักเข้าใจผิด
    • 👶AI พื้นฐาน
    • 👶Git พื้นฐาน
      • Git branching strategy
    • 👶Cloud พื้นฐาน
    • 👶UML พื้นฐาน
      • Activity Diagram
      • Class Diagram
      • Sequence Diagram
      • Use case Diagram
      • บทสรุปการใช้ UML
    • 👶Data Scientist
      • การเลือก Algorithms ให้ AI (1/5)
      • การเตรียมข้อมูลให้ AI (2/5)
      • หลักการตั้งคำถามให้ AI (3/5)
      • แฉความลับของ AI Model (4/5)
      • หัดเขียน AI จาก AI ของคนอื่น (5/5)
    • 👶DevOps พื้นฐาน
    • 👶Docker ขั้นพื้นฐาน
      • Image and Container
      • แชร์ Docker Image ที่สร้างไว้
    • 👶Microservices พื้นฐาน
      • Microservices ที่ดีมีลักษณะยังไง
      • Microservices Tips
      • จาก Monolith สู่ Microservices
    • 👶ความรู้พื้นฐานในการทำเว็บ
    • 👦Bottlenecks of Software
      • หัวใจที่สำคัญที่สุดของฐานข้อมูล
    • 👦Agile Methodology
      • Agile in a Nutshell
      • Software Development Life Cycle
      • Code Review
    • 👦Security พื้นฐาน
      • การเก็บรหัสผ่านที่ถูกต้อง
      • Security in actions
        • Hash function
      • Security Principles
      • 😎The Matrix 1
      • 😎The Matrix 2
      • HTTPS in a nutshell
    • 👦SOLID Design Principles
      • มารู้จักกับ SOLID กันดีกว่า
      • Single-Responsibility Principle
      • Open/Closed Principle
      • Liskov Substitution Principle
      • Interface Segregation Principle
      • Dependency-Inversion Principle
  • Cloud Computing
    • 👶Microsoft Azure 101
      • สมัคร Microsoft Azure
      • รู้จักกับ Resource Groups
      • สร้างเว็บตัวแรกกัน
      • สร้าง Virtual Machine กัน
      • ประเภทของคลาว์เซอร์วิส
      • มาสร้าง Logic App กัน
      • มาสร้าง Function App กัน
      • คลาว์คิดเงินยังไง ?
      • Cloud Native
      • Guideline for Cloud scaling
      • Auto Scaling
    • 👶Azure App Services
    • 👶App Service Plan
    • 👶Azure Storage
      • Blob storage
        • ลองสร้างที่เก็บไฟล์กันเลย
        • เข้าใจ Blob storage ให้มากขึ้น
        • ลองเขียนโค้ดอัพโหลดไฟล์กันบ้าง
        • สร้างเว็บจากที่ฝากไฟล์บนคลาว์
    • 👶Azure Bot Service
      • Bot เข้าใจเราได้ยังไงกันนะ
    • 👶Azure Cognitive Services
      • การสร้าง Cognitive Services
      • การ Login ด้วยใบหน้า
      • อ่านลายมือจากรูปเป็นตัวอักษร (OCR)
      • เขียน AI แยกของต่างๆทำยังไง?
      • เขียนแอพ ทายอายุ บอกเพศ ง่ายจิ๊ดเดียว
      • เขียนแอพให้ AI อธิบายรูปเป็นภาษาคน
    • 👶Machine Learning Studio
      • มาสร้าง AI ของแท้ตัวแรกของเรากัน
      • สร้าง AI ตัดสินใจอนุมัติบัตรเครดิต 💳
      • ลองเรียกใช้ AI ของเรากัน
    • 👶Azure Service Fabric
      • สร้าง Service Fabric กัน
    • 👶Blockchain
      • Blockchain ทำงานยังไง ?
      • Consensus Algorithm คืออะไร ?
      • สร้าง Blockchain ใช้เองกัน !
      • หัดเขียน Smart Contract กัน
    • 👶Power BI
    • 👶Azure Web App
      • เซิฟเวอร์บนคลาว์ ราคา? ต่าง?
    • 👶Azure DevOps
      • เล่น Azure DevOps กัน
      • เล่นกับ Repository
      • ลองทำ Continuous Integration (CI)
      • ลองทำ Continuous Delivery (CD)
      • เล่น Kanban Board
    • 🤠Cloud Playground
      • การป้องกันความลับหลุดตอนที่ 1
      • การป้องกันความลับหลุดตอนที่ 2
      • การป้องกันความลับหลุดตอนที่ 3
      • การป้องกันความลับหลุดตอนจบ
  • Software Testing
    • 👦Test-First Design
    • 👦Test-Driven Development
      • 1.มารู้จักกับ TDD กันดีกว่า
      • 2.Test cases เขาเขียนกันยังไงนะ
      • 3.เครื่องมือในการทดสอบ
      • 4.การใช้ Theory และ InlineData
      • 5.โค้ดที่ทดสอบได้
      • 6.Mantra of TDD
      • 7.Functional & None-Functional testing
      • 8.Manual vs Automation testing
      • 9.Automation Frameworks in .NET
      • 10.Mock Framework
      • 11.มาเรียนการใช้ Moq กันเถอะ
      • 12.สรุป
  • Web
    • 👦Web API
      • 1.Web API คืออะไร
      • 2.ติดตั้ง .NET Core SDK
      • 3.สร้าง Web API ตัวแรกกัน
      • 4.Verbs
      • 5.Swagger เพื่อคู่ API
      • 6.การใช้ Model
      • 7.เรียก Web API ผ่าน Postman
      • 8.มาจัดกลุ่ม API กัน (1/2)
      • 9.มาจัดกลุ่ม API กัน (2/2)
  • Software Design
    • 🤴Design Patterns
      • 🦈Creational patterns
        • Abstract Factory
        • Builder
        • Factory Method
        • Prototype
        • Singleton
      • 🦈Structural patterns
        • Adapter
        • Bridge
        • Decorator
        • Facade
        • Proxy
      • 🦈Behavioral patterns
        • Chain of Responsibility
        • Command
        • Iterator
        • Mediator
        • Memento
        • Observer
        • State
        • Strategy
        • Template Method
        • Visitor
Powered by GitBook
On this page
  • Iterator
  • 🎯 เป้าหมายของ pattern นี้
  • ✌ หลักการแบบสั้นๆ
  • 😢 ปัญหา
  • 😄 วิธีแก้ไข
  • 📌 โครงสร้างของ pattern นี้
  • 🛠 ตัวอย่างการนำไปใช้งาน
  • 👍 ข้อดี
  • 👎 ข้อเสีย
  • ‍‍📝 Code ตัวอย่าง

Was this helpful?

Export as PDF
  1. Software Design
  2. Design Patterns
  3. Behavioral patterns

Iterator

PreviousCommandNextMediator

Last updated 5 years ago

Was this helpful?

Iterator

Provide a way to access the elements of an aggregate object sequentially without exposing its underlying representation.

🎯 เป้าหมายของ pattern นี้

ช่วยให้เราเข้าไปทำงานกับข้อมูลที่เป็น collection ได้ทุกรูปแบบ

✌ หลักการแบบสั้นๆ

  1. แยกงานที่ใช้ในการท่องไปใน collection ออกมาให้ class อื่นทำงาน (เราเรียก class ใหม่นี้ว่า Iterator)

  2. ให้ collection class สามารถสร้าง Iterator object ได้

  3. ใครที่ต้องการเข้าถึงข้อมูลของ collection ให้ใช้งานผ่าน iterator object ที่ collection class สร้างให้แทน

😢 ปัญหา

วันหนึ่งนั่งดูดเนื้ออยู่ชิวๆก็คิดถึงวันวานที่นั่งเรียนวิชา Algorithm ขึ้นมา เป็นเรื่องการเก็บข้อมูลที่เป็น collection ซึ่งจำได้รางๆว่ามันมี collection หลากหลายแบบเลย เช่น LinkedList, Stacks, Trees และผองเพื่อนที่ตามมาอีกบานตะไท ซึ่งบางตัวก็เรียบง่าย บางตัวก็วุ่นวายปะปนกันไป

แต่ถ้าเราต้องทำงานกับ collection หลายๆแบบเข้าซักวันนึงละ? เช่น ในครั้งแรกส่งข้อมูลมาในรูปแบบ LinkedList ต่อมาเป็นส่งเข้ามาในรูปแบบ Stack และต่อมาเป็นแบบ Random access tree ละ ชีวิตเราคงจะวุ่นวายเป็นแน่ เพราะ collection แต่ละชนิดจะมีวิธีในการเข้าถึงข้อมูลภายในตัวมันเองที่ไม่เหมือนกันเลย และต่อให้เป็น collection แบบเดียวกัน แต่ถ้าเลือกคนละ algorithm วิธีเข้าถึงข้อมูลก็ต่างกันคนละโลกเช่นกัน เช่น Binary tree ซึ่งมี algorithm ที่ทำงานด้วยหลายแบบ Inorder, Preorder, Postorder บลาๆ (นี่ผมพิมพ์อะไรลงไป น่าจะเป็นผลกระทบจากการดูดเนื้อแน่ๆ)

แค่คิดตามก็ปวดตับละนั่นเพราะ ทุกครั้งที่โปรแกรมเราทำงานกับ collection ใหม่ๆ นั่นหมายถึงเราต้องเพิ่ม Algorithm ในการทำงานกับ collection พวกนั้นด้วยไงละ สรุปงานของเราคือเขียนโปรแกรมหรือมานั่งเขียน Algorithm ในการใช้งาน collection กันละเนี่ย!!

แล้วเราจะแก้ปัญหานี้ยังไงดีเพื่อป้องกันเหตุการณ์ เพิ่ม 10 collection จะต้องคอยเพิ่ม 10 Algorithm เพื่อที่จะทำงานกับข้อมูลของ collection พวกนั้นด้วย (หรือจริงๆแค่หยุดดูดเนื้อก็หายเพ้อแล้วหว่า)

😄 วิธีแก้ไข

ขณะที่กำลังเครียดจัดเลยปุ๋นเนื้อคำโตเข้าต่อ ทำให้เห็นภาพหุ่นยนต์แรคคูนสีฟ้ามายืนข้างกาย แล้วแรคคูนสีฟ้าก็บอกกับเราว่า

วันนี้ขอเสนอตอน Iterator Pattern นะก๊าฟฟฟฟฟ ซึ่งแน่นอนภาพหลอนยังไม่เลือนหาย เจ้าแรคคูนสีฟ้าก็ชิ่งพล่ามต่อว่า

เฮ้โนบิตุเอ็งจงแยก Algorithm ในการทำงานกับ collection ออกไปไว้กับ object อื่นเด้ ซึ่งเจ้า object พวกนั้นม่อนขอเรียกมันว่า Iterator นะพวก!!

แล้วเจ้า Iterator object จะต้องเป็นคนจัดการทุกสิ่งทุกอย่างที่จำเป็นต่อการทำงานกับ collection ด้วย เช่น ตำแหน่งปัจจุบัน, เหลือข้อมูลอีกกี่ตัวที่ต้องทำต่อ บลาๆ

ซึ่งเจ้า Iterator มันจะต้องมี method ให้ client สามารถดึงข้อมูลแต่ละตัวตามลำดับของ collection ด้วย ซึ่งเจ้า method นี้จะค่อยๆคายค่าใน collection ออกมาให้ทีละตัวตามลำดับ ตั้งแต่ตัวแรกยันตัวสุดท้ายด้วยนะ

และจากที่พูดมาทั้งหมด client จะทำงานผ่าน Iterator interface เท่านั้นมันจะได้ไม่เกิด coupling ขึ้นยังไงละ เพียงเท่านี้เอ็งก็สามารถทำงานกับ collection ได้ทุกประเภทแบ๊ว ตามรูปเบย

เมื่อพูดจบเจ้าแรคคูนสีฟ้าก็ตบหน้าเราเข้า 1 ฉาด แล้วตะโกนใส่เราว่า กรู๊วไม่ใช่แรคคูนนะเฟร้ยก่อนจะจางหายไป พร้อมกับสติที่กลับมาของเรา

ทำให้เรารู้ว่าต่อไปนี้เราก็ทำงานกับ collection ได้ทุกประเภทบนโลกแล้ว โดยที่ client ไม่ต้องสนใจเลยว่ามันเป็น collection ประเภทไหน เพราะมันทำงานกับ Iterator interface เท่านั้น

📌 โครงสร้างของ pattern นี้

อธิบาย 1.Iterator - เป็น Interface ต้นแบบของตัวที่แยก Algorithm ในการทำงานกับ collection ออกมา และจะต้องมี method สำหรับดึงข้อมูลใน collection ออกมาตามลำดับ 2.Concrete Iterators - เป็น concreate class ที่มี algorithm ในการเข้าถึงข้อมูลของ collection ในรูปแบบของมัน 3.Collection Interface - เป็น interface ที่เป็นต้นแบบของ concreate collection ซึ่งตัวมันจะต้องมี method มาตรฐานในการสร้าง concreate iterator ที่เหมาะสมกับมัน 4.Concrete Collections - เป็นตัวตัดสินใจที่แท้จริงว่า iterator ตัวไหนเหมาะสมกับมัน 5.Client - เมื่อต้องการทำงานกับ collection จะทำงานผ่าน interface ทำให้ client ไม่ต้องสนใจว่า collection จริงๆของมันคืออะไร

🛠 ตัวอย่างการนำไปใช้งาน

ในรอบนี้เราจะลองเขียน collection 2 แบบคือแบบ

1.Queue (FIFO - First-In-First-Out)

ซึ่งภายในมีข้อมูลอยู่คือ { 1, 2, 3, 4 } ตามลำดับ

2.Stack (LIFO - Last-In-First-Out)

ซึ่งภายในมีข้อมูลอยู่คือ { 1, 2, 3, 4 } ตามลำดับ

โดยที่เราจะใช้ Iterator Pattern มาช่วยทำให้เราเขียน code แบบเดียวแต่ทำงานได้กับ collection ทั้ง 2 แบบ ปะลองไปดูโค้ดตัวอย่างกันเลย

👍 ข้อดี

  • สามารถทำงานได้กับ collection ทุกรูปแบบโดยใช้โค้ดตัวเดียวกัน

  • ถูกหลัก Single Responsibility Principle

  • ถูกหลัก Open/Closed Principle

👎 ข้อเสีย

  • ภาษาสมัยใหม่ส่วนใหญ่จะมีเรื่องพวกนี้อยู่แล้ว ดังนั้นไปศึกษาที่ภาษานั้นๆเลยจะดีกว่าที่จะมาเขียนใหม่

  • ถ้าโปรแกรมเราใช้แค่ collection ธรรมดาอย่าใช้ pattern นี้ เพราะมันจะทำให้โค้ดยากขึ้นโดยใช่เหตุ

‍‍📝 Code ตัวอย่าง

using System;

// Iterator Interface
interface IIterator
{
    bool HasMore();
    object GetNext();
}

// Collection Interface
interface ICollection
{
    IIterator CreateIterator();
}

// Concreate Iterator
class QueueIterator : IIterator
{
    private int currentIndex;
    private int[] data;

    public QueueIterator(int[] data)
        => this.data = data;

    public bool HasMore()
        => currentIndex < data.Length;

    public object GetNext()
        => data[currentIndex++];
}
class StackIterator : IIterator
{
    private int currentIndex;
    private string[] data;

    public StackIterator(string[] data)
    {
        this.data = data;
        currentIndex = data.Length - 1;
    }

    public bool HasMore()
        => currentIndex >= 0;

    public object GetNext()
        => data[currentIndex--];
}

// Concreate Collection
class Queue : ICollection
{
    private int currentIndex = 0;
    private int[] storedData = new int[4];

    public IIterator CreateIterator()
        => new QueueIterator(storedData);

    public void Enqueue(int data)
    { 
        if(currentIndex < storedData.Length)
        {
            storedData[currentIndex++] = data;
        }
    }
}
class Stack : ICollection
{
    private int currentIndex = 0;
    private string[] storedData = new string[4];

    public IIterator CreateIterator()
        => new StackIterator(storedData);

    public void Push(string data)
    { 
        if(currentIndex < storedData.Length)
        {
            storedData[currentIndex++] = data;
        }
    }
}

// Client
class Program
{
    static void Main()
    {
        var queue = new Queue();
        queue.Enqueue(1);
        queue.Enqueue(2);
        queue.Enqueue(3);
        queue.Enqueue(4);

        Console.WriteLine("แสดงข้อมูลใน Queue");
        ShowAllDataInCollection(queue.CreateIterator());

        Console.WriteLine();

        var stack = new Stack();
        stack.Push("1");
        stack.Push("2");
        stack.Push("3");
        stack.Push("4");
        Console.WriteLine("แสดงข้อมูลใน Stack");
        ShowAllDataInCollection(stack.CreateIterator());
    }

    static void ShowAllDataInCollection(IIterator iterator)
    {
        while(iterator.HasMore())
        {
            Console.WriteLine(iterator.GetNext());
        }
    }
}

Output

แสดงข้อมูลใน Queue
1
2
3
4

แสดงข้อมูลใน Stack
4
3
2
1

Note สำหรับภาษา C# นั้นทีมพัฒนาได้เตรียม interface สำหรับทำ Iterator ไว้ให้แล้วนะโยมนะ ซึ่ง interface ตัวนั้นชื่อว่า IEnumerable โยมไม่ต้องไปเขียนใหม่ให้เมื่อยมือหรอก

🤴
🦈
กดที่นี่เพื่ออ่านต่อ
img
img
img
img
img