Design Patterns: Exploring Embedded C Language Implementation – Iterator Pattern

Introduction:This article will briefly describe the Iterator Pattern from the book Head First Design Patterns and implement this pattern using C language. It will also explain the key features of C language used in the implementation.Background of the Iterator Pattern: In the book Head First Design Patterns, the background story of the Iterator Pattern is about the merger of Object Village and Pancake House. After the merger, the new restaurant plans to use the Pancake House’s menu as the breakfast menu and the Object Village’s menu as the lunch menu. However, the Pancake House’s menu is implemented using ArrayList<span><span>, while the restaurant's menu is implemented using an array, and both are unwilling to change their menu implementation methods due to a large amount of code dependent on the original data structures.</span></span> At this point, if the waitress wants to implement the menu printing function, she needs to know how to traverse these two different data structures, which complicates the code and makes it difficult to maintain. If more restaurants join later, and their menus are implemented with different data structures, the problem will become even more serious. To solve this problem, the Iterator Pattern is introduced by creating an iterator to encapsulate the “process of traversing each object in the collection,” allowing the waitress to traverse the menu without needing to understand the specific implementation details of the menu, thus achieving decoupling of the client code from the menu data structure.Pattern Definition: Provides a way to sequentially access the elements of an aggregate object without exposing its internal representation.Component Diagram / Implementation Idea: The diagram first defines the menu structure for both the Pancake House and the restaurant menu to share. It also defines a unified abstract interface for the Iterator, which is used to encapsulate the process of traversing objects mentioned above. In the Pancake House and restaurant menus, each will define its own iterator, implementing the (*hasNext) and (*next) interfaces.Design Patterns: Exploring Embedded C Language Implementation - Iterator Pattern It also defines a Waitress object to associate the menus of the Pancake House and the restaurant.Example Code Snippet:

  • Define Menu Item:
typedef struct{char name[50];char description[100];int vegetarian;double price;}MenuItem;
  • Iterator Interface:
typedef struct{int (*hasNext)(void*);MenuItem* (*next)(void*);}Iterator;
  • Pancake House Menu:
typedef struct PancakeHouseMenu PancakeHouseMenu;struct PancakeHouseMenu{MenuItem items[10];int count;Iterator iterator;PancakeIteratorState iteratorState;};
  • Pancake House Iterator Interface Implementation
int pancakeIteratorHasNext(void* state){PancakeIteratorState* iteratorState = (PancakeIteratorState*)state;return iteratorState-&gt;position &lt; iteratorState-&gt;menu-&gt;count;}MenuItem* pancakeIteratorNext(void* state){ PancakeIteratorState* iteratorState = (PancakeIteratorState*)state; if(pancakeIteratorHasNext(state)){    MenuItem* item = &amp;iteratorState-&gt;menu-&gt;items[iteratorState-&gt;position];    iteratorState-&gt;position++;    return item;  }  return NULL;}     
  • Restaurant Menu:
typedef struct{MenuItem items[5];int position;Iterator iterator;DinerMenu;
  • Restaurant Iterator Interface Implementation
int dinerIteratorHasNext(void* menu) {DinerMenu* dinerMenu=(DinerMenu*)menu;return dinerMenu-&gt;position &lt; MAXDINER_ITEMS &amp;&amp;       dinerMenu-&gt;items[dinerMenu-&gt;position].price != 0.0;}MenuItem* dinerIteratorNext(void *menu){DinerMenu* dinerMenu=(DinerMenu*)menu;if(dinerIteratorHasNext(menu)) {  return &amp;dinerMenu-&gt;item[dinerMenu-&gt;position++];}return NULL;}
  • Waitress Class:
typedef struct {  PancakeHouseMenu* pancakeMenu;  DinerMenu* dinerMenu;}Waitress;
  • Print Menu:
void printMenu(waitress* waitness){{ // Print Pancake House menu ... // Print restaurant menu ... }
  • Test Code

Design Patterns: Exploring Embedded C Language Implementation - Iterator PatternTest Result Output:Design Patterns: Exploring Embedded C Language Implementation - Iterator PatternFeatures of C Language Used: Using function pointers to implement: 1. Callback function mechanism: The Iterator defines function pointers (*hasNext)(void*) and Menu*(*next)(void*). 2. Implementing polymorphism: Different menu types achieve the same interface with different behaviors through function pointers.Conclusion: This article explored the implementation of the Iterator Pattern through C language and the story background from the book.Code Repository:

https://github.com/MicroDevLog/DesignPatternInC

References:

[1]. Head First Design Patterns, China Electric Power Press.

[2]. Software Architecture Patterns, Volume I

Previous Issues:Design Patterns: Exploring Embedded C Language Implementation – 0. IntroductionDesign Patterns: Exploring Embedded C Language Implementation – 1. Strategy PatternDesign Patterns: Exploring Embedded C Language Implementation – 2. Observer PatternDesign Patterns: Exploring Embedded C Language Implementation – 3. Decorator PatternDesign Patterns: Exploring Embedded C Language Implementation – 4. Simple Factory PatternDesign Patterns: Exploring Embedded C Language Implementation – 5. Factory Method PatternDesign Patterns: Exploring Embedded C Language Implementation – 6. Abstract Factory PatternDesign Patterns: Exploring Embedded C Language Implementation – 7. Singleton PatternDesign Patterns: Exploring Embedded C Language Implementation – 8. Command PatternDesign Patterns: Exploring Embedded C Language Implementation – 9. Adapter PatternDesign Patterns: Exploring Embedded C Language Implementation – 10. Template Method PatternClick the card below to follow this public account:: If you like it, remember to “share” and “recommend” or “like” or “comment“.

Leave a Comment