This is the 7th day of my participation in the August Text Challenge.More challenges in August
Preface: the iterator pattern is not used much, because both C# and Java have been wrapped for me, but do you know the nature of the things you often use?
You can see how C# foreach loops are implemented by looking at the iterator pattern. My other article on the nature of C# foreach loops and enumerators explains the nature of foreach, which uses the iterator pattern.
By convention, the example goes up. (write a few hours browser crash, I see in the auto save ah, the result has no content, again masturbate a concise point of it)
1. Restaurant menu consolidation
Now there are two restaurants, one for breakfast and one for dinner. They all have their own way of managing the menu, and now the two restaurants have merged and they need to unify the menu, so let me see what they look like in the original.
The menu items on both menus are the same
A menu item
Public class MenuItme {// public string Name {get; set; } public string Description {get; set; } public bool Vegetarian {get; set; } public double Price {get; set; } public MenuItme(string name, string description, bool vegetarian, double price) { Name = name; Description=description; Vegetarian = vegetarian; Price = price; }}Copy the code
Breakfast menu, using List management, unlimited length
public class BreakFastMenu { private List<MenuItme> menuItmes; public BreakFastMenu() { menuItmes = new List<MenuItme>(); AddItem(" Meatloaf ", "yummy ", false, 7); // Menu item... } public void AddItem(string name, string description, bool vegetarian, double price) { MenuItme menuItme = new MenuItme(name, description, vegetarian, price); menuItmes.Add(menuItme); } public List<MenuItme> GetMenuItmes() { return menuItmes; }}Copy the code
Dinner menu, using array management, limit length to 6
public class DinerMenu { static readonly int Max_Items = 6; private int numberOfImtes = 0; private MenuItme[] menuItmes; public DinerMenu() { menuItmes = new MenuItme[Max_Items]; AddItem(" Stir-fry toad ", "Pay attention to the heat ", false, 42); // Menu item... } public void AddItem(string name, string description, bool vegetarian, double price) { MenuItme menuItme = new MenuItme(name, description, vegetarian, price); If (numberOfImtes >= Max_Items) {console. WriteLine(" Menu is full "); } else { menuItmes[numberOfImtes] = menuItme; numberOfImtes++; } } public MenuItme[] GetMenuItmes() { return menuItmes; }}Copy the code
When the two restaurants merged, they had to print out breakfast and dinner menus for customers.
BreakFastMenu breakFastMenu = new BreakFastMenu(); List<MenuItme> breakFastMenus = breakFastMenu.GetMenuItmes(); DinerMenu dinerMenu = new DinerMenu(); MenuItme[] dinerMenus = dinerMenu.GetMenuItmes(); For (int I = 0; i < breakFastMenus.Count; i++) { Console.WriteLine(breakFastMenus[i].Name); } // Print dinner for (int I = 0; i < dinerMenus.Length; i++) { Console.WriteLine(dinerMenus[i].Name); }Copy the code
In this way we always need to deal with two menus, and if we want to print vegetarian, we also need to loop through both menus.
If we add a third restaurant merge, we need to recycle three times, which obviously makes our system difficult to maintain.
Now how can we improve
Second, improve menu implementation
How do we encapsulate the traversal set caused by different sets of classes
For both breakfast and dinner we use brackets [] to take menu items and set length to limit length.
Now we’ll create an object, call it an Iterator, that encapsulates “the process of walking through every object in the collection.”
For the List
Iterator iterator = breakFastMenu.CreateIterator();
while (iterator.HasNext)
{
MenuItme menuItme = iterator.Next();
}
Copy the code
For an array of
Iterator iterator = dinerFastMenu.CreateIterator();
while (iterator.HasNext)
{
MenuItme menuItme = iterator.Next();
}
Copy the code
The traversal of both sets is now uniform, and this is the iterator pattern. The first thing we need to know about iterators is that they depend on an iterator interface.
This interface may have a HasNext() method and it’s not clear if we have any more elements in this set.
The Next() method returns the Next object in the collection. Once we have this interface, we can implement iterators for various collections of objects.
Now to transform the dinner menu, first we need to define an iterator interface
public interface Iterator
{
bool HasNext();
Object Next();
}
Copy the code
Add a dinner menu iterator
public class DinerMenuIterator : Iterator { MenuItme[] menuItmes; int position = 0; public DinerMenuIterator(MenuItme[] menuItmes) { this.menuItmes = menuItmes; } public bool HasNext() {// Because the array is fixed length, check not only the array, but also the specified position is empty, If is empty behind, there is no menu item if (position > = menuItmes. Length | | menuItmes [position] = = null) return false. else return true; } public object Next() { MenuItme menuItme = menuItmes[position]; position++; return menuItme; }}Copy the code
Rewrite the dinner menu with iterators
public class DinerMenu { static readonly int Max_Items = 6; private int numberOfImtes = 0; private MenuItme[] menuItmes; public DinerMenu() { menuItmes = new MenuItme[Max_Items]; AddItem(" Stir-fry toad ", "Pay attention to the heat ", false, 42); // Menu item... } public void AddItem(string name, string description, bool vegetarian, double price) { MenuItme menuItme = new MenuItme(name, description, vegetarian, price); If (numberOfImtes >= Max_Items) {console. WriteLine(" Menu is full "); } else { menuItmes[numberOfImtes] = menuItme; numberOfImtes++; } } public Iterator CreateIterator() { return new DinerMenuIterator(menuItmes); } //public MenuItme[] GetMenuItmes() //{ // return menuItmes; / /}}Copy the code
Similarly, we added iterators for breakfast
public class BreakFastIterator: Iterator { List<MenuItme> menuItmes; int position = 0; public BreakFastIterator(List<MenuItme> menuItmes) { this.menuItmes = menuItmes; } public bool HasNext() { if (position >= menuItmes.Count) return false; else return true; } public object Next() { MenuItme menuItme = menuItmes[position]; position++; return menuItme; }}Copy the code
Rewrite the breakfast menu with iterators
public class BreakFastMenu { private List<MenuItme> menuItmes; public BreakFastMenu() { menuItmes = new List<MenuItme>(); AddItem(" Meatloaf ", "yummy ", false, 7); // Menu item... } public void AddItem(string name, string description, bool vegetarian, double price) { MenuItme menuItme = new MenuItme(name, description, vegetarian, price); menuItmes.Add(menuItme); } public Iterator CreateIterator() { return new BreakFastIterator(menuItmes); } //public List<MenuItme> GetMenuItmes() //{ // return menuItmes; / /}}Copy the code
Ok, let’s try the iterator in action
Iterator pattern
After the second step, we have basically implemented the iterator mode. Finally, we will improve the print menu and manage the unified interface for the menu.
Define a Menu interface
public interface Menu
{
Iterator CreateIterator();
}
Copy the code
Let breakfast and dinner are implemented Menu interface, and package a new Menu print
public class NewMenu { Menu breakFastMenu; Menu dinerMenu; public NewMenu(Menu breakFastMenu, Menu dinerMenu) { this.breakFastMenu = breakFastMenu; this.dinerMenu = dinerMenu; } public void PrintMenu() { Iterator breakFastIterator = breakFastMenu.CreateIterator(); Console.WriteLine(" new menu -------- breakfast "); PrintMenu(breakFastIterator); Console.WriteLine(" New menu -------- dinner "); Iterator dinerIterator = dinerMenu.CreateIterator(); PrintMenu(dinerIterator); } private void PrintMenu(Iterator Iterator) {while (iterator.hasnext ()) {// Get next item MenuItme MenuItme = (MenuItme)iterator.Next(); Console.WriteLine(menuItme.Name); }}}Copy the code
Iterator pattern definition:
Iterator pattern: Provides a way to access the elements of a collection object sequentially without exposing their internal representation.
The iterator pattern allows us to walk around each element in the collection without exposing its internal representation.
Place the task of walking on the iterator, not the collection. This simplifies the interface and implementation of collections and puts responsibilities in their place.