把迭代器模式和组合模式放在同一篇的原因是其联系比较紧密。
一、迭代器模式
1.1迭代器模式定义
迭代器模式提供一种方法顺序访问一个聚合对象中的各个元素,而不是暴露其内部的表示。
这个模式提供了一种方法,可以顺序访问一个聚合对象中的元素,而不用知道内部怎么表示的。为了更好的理解迭代器模式,我们举个例子。
1.2迭代器例子
下面使用head first设计模式中的例子,使用迭代器模式来演示早餐和晚餐菜单的显示。由于早餐和晚餐其数据结构不同,由于早餐店和晚餐店需要合并,所以需要一个统一的菜单:即菜单项结构相同。下面先介绍一下菜单项的结构。
public class MenuItem { private string name; private string description; private bool vegetarin; private double price; public MenuItem(string name, string description, bool vegetarin, double price) { this.name = name; this.description = description; this.vegetarin = vegetarin; this.price = price; } public string GetName() { return name; } public double GetPrice() { return price; } public bool IsVegetarian() { return vegetarin; } public string GetDescription() { return description; } }
接下来分别来看一下早餐类和晚餐类,早餐类的结构是ArrayList,晚餐类的结构是数组:
public class BreakfastMenu { ArrayList menuItems; public BreakfastMenu() { menuItems = new ArrayList(); AddItem("牛奶", "牛奶description", false, 3.0); AddItem("油条","油条description",false,1.0); AddItem("馒头","馒头description",true,1.0); AddItem("豆浆", "DoujiangDescription", true, 1.5); } public void AddItem(string name, string description, bool vegetarian, double price) { MenuItem menuItem = new MenuItem( name, description, vegetarian, price); menuItems.Add(menuItem); } public ArrayList GetMenuItems() { return menuItems; } } public class DinerMenu { static readonly int Max_ITEMS = 6; int numberOfItems = 0; MenuItem[] menuItems; public DinerMenu() { menuItems = new MenuItem[Max_ITEMS]; AddItem("香菇豆腐饭", "香菇豆腐", false, 10.5); AddItem("蛋炒饭","哈哈",false,8.5); AddItem("鱼香肉丝","你猜",true,15.5); } public void AddItem(string name, string description, bool vegetarian, double price) { MenuItem menuItem = new MenuItem(name, description, vegetarian, price); if (numberOfItems>Max_ITEMS) { Console.WriteLine("菜单已满"); } else { menuItems[numberOfItems] = menuItem; numberOfItems++; } } public MenuItem[] GetMenuItems() { return menuItems; } }
接下来看一下客户端是如何来把各种饭菜打印出来的:
BreakfastMenu breakfastMenu = new BreakfastMenu(); ArrayList breakfastItems = breakfastMenu.GetMenuItems(); DinerMenu dinerMenu = new DinerMenu(); MenuItem[] lunchItems = dinerMenu.GetMenuItems(); for (int i = 0; i < breakfastItems.Count; i++) { MenuItem menuItem = breakfastItems[i] as MenuItem; Console.WriteLine(menuItem.GetName()+" "+menuItem.GetPrice().ToString()+" "+menuItem.GetDescription().ToString()); } for (int j = 0; j < lunchItems.Length; j++) { MenuItem lunchItem = lunchItems[j] ; if (lunchItem!=null) { Console.WriteLine(lunchItem.GetName() + " " + lunchItem.GetPrice().ToString() + " " + lunchItem.GetDescription().ToString()); } } Console.ReadKey();
很明显上面的遍历的算法是一样的,因为早餐和晚餐的数据结构的不同导致了代码不能复用,当然可以使用泛型解决该问题。但是本文需要使用的是迭代器设计模式。
为了可以使用相同的遍历方法,我们定义一个接口迭代器:
public interface Iterator { /// <summary> /// 用来判断下一个元素是否为空 /// </summary> /// <returns></returns> bool HasNext(); /// <summary> /// 用来获取当前元素 /// </summary> /// <returns></returns> object Next(); }
我们希望的是能通过迭代器实现下面的操作:
while (iterator.HasNext()) { MenuItem menuitem = (MenuItem)iterator.Next; Console.WriteLine(menuitem.GetName() + " " + menuitem.GetPrice().ToString() + " " + menuitem.GetDescription().ToString()); }
接下来的目标就是创建早晚餐菜单的迭代器。
public class BreakfastIterator : Iterator { private ArrayList items; private int position; public BreakfastIterator(ArrayList arrayList) { items = arrayList; } public bool HasNext() { if (position>items.Count||items[position]==null) { return false; } else { return true; } } public object Next() { MenuItem menuItem = items[position] as MenuItem; position = position + 1; return menuItem; } } public class DinnerIterator : Iterator { private MenuItem[] items; private int position = 0; public DinnerIterator(MenuItem[] items) { this.items = items; } public bool HasNext() { if (position > items.Length || items[position] == null) { return false; } else { return true; } } public object Next() { MenuItem menuItem = items[position] as MenuItem; position = position + 1; return menuItem; } }
可以定义一个菜单接口,来创建迭代器。分别让各个菜单去实现这个接口,下面给出完整的代码:
using System; using System.Collections; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace IteratorPattern { class Program { static void Main(string[] args) { //BreakfastMenu breakfastMenu = new BreakfastMenu(); //ArrayList breakfastItems = breakfastMenu.GetMenuItems(); //DinerMenu dinerMenu = new DinerMenu(); //MenuItem[] lunchItems = dinerMenu.GetMenuItems(); //for (int i = 0; i < breakfastItems.Count; i++) //{ // MenuItem menuItem = breakfastItems[i] as MenuItem; // Console.WriteLine(menuItem.GetName() + " " + menuItem.GetPrice().ToString() + " " + menuItem.GetDescription().ToString()); //} //for (int j = 0; j < lunchItems.Length; j++) //{ // MenuItem lunchItem = lunchItems[j]; // if (lunchItem != null) // { // Console.WriteLine(lunchItem.GetName() + " " + lunchItem.GetPrice().ToString() + " " + lunchItem.GetDescription().ToString()); // } //} IMenu breakfastMenu = new BreakfastMenu(); IMenu dinnerMenu = new DinnerMenu(); breakfastMenu.CreateIterator(); Iterator dinnerIterator = dinnerMenu.CreateIterator(); Iterator breakfastIterator = breakfastMenu.CreateIterator(); Print(breakfastIterator); Print(dinnerIterator); Console.ReadKey(); } static void Print(Iterator iterator) { while (iterator.HasNext()) { MenuItem menuItem = (MenuItem)iterator.Next(); Console.WriteLine(menuItem.GetName() + " " + menuItem.GetPrice().ToString() + " " + menuItem.GetDescription().ToString()); } } } public class MenuItem { private string name; private string description; private bool vegetarin; private double price; public MenuItem(string name, string description, bool vegetarin, double price) { this.name = name; this.description = description; this.vegetarin = vegetarin; this.price = price; } public string GetName() { return name; } public double GetPrice() { return price; } public bool IsVegetarian() { return vegetarin; } public string GetDescription() { return description; } } public class BreakfastMenu : IMenu { ArrayList menuItems; public BreakfastMenu() { menuItems = new ArrayList(); AddItem("牛奶", "牛奶description", false, 3.0); AddItem("油条","油条description",false,1.0); AddItem("馒头","馒头description",true,1.0); AddItem("豆浆", "DoujiangDescription", true, 1.5); } public void AddItem(string name, string description, bool vegetarian, double price) { MenuItem menuItem = new MenuItem( name, description, vegetarian, price); menuItems.Add(menuItem); } public ArrayList GetMenuItems() { return menuItems; } public Iterator CreateIterator() { return new BreakfastIterator(menuItems); } } public class DinnerMenu:IMenu { static readonly int Max_ITEMS = 6; int numberOfItems = 0; MenuItem[] menuItems; public DinnerMenu() { menuItems = new MenuItem[Max_ITEMS]; AddItem("香菇豆腐饭", "香菇豆腐", false, 10.5); AddItem("蛋炒饭","哈哈",false,8.5); AddItem("鱼香肉丝","你猜",true,15.5); } public void AddItem(string name, string description, bool vegetarian, double price) { MenuItem menuItem = new MenuItem(name, description, vegetarian, price); if (numberOfItems>Max_ITEMS) { Console.WriteLine("菜单已满"); } else { menuItems[numberOfItems] = menuItem; numberOfItems++; } } public MenuItem[] GetMenuItems() { return menuItems; } public Iterator CreateIterator() { return new DinnerIterator(menuItems); } } public interface Iterator { /// <summary> /// 用来判断下一个元素是否为空 /// </summary> /// <returns></returns> bool HasNext(); /// <summary> /// 用来获取当前元素 /// </summary> /// <returns></returns> object Next(); } public class BreakfastIterator : Iterator { private ArrayList items; private int position; public BreakfastIterator(ArrayList arrayList) { items = arrayList; } public bool HasNext() { if (position>=items.Count||items[position]==null) { return false; } else { return true; } } public object Next() { MenuItem menuItem = items[position] as MenuItem; position = position + 1; return menuItem; } } public class DinnerIterator : Iterator { private MenuItem[] items; private int position = 0; public DinnerIterator(MenuItem[] items) { this.items = items; } public bool HasNext() { if (position > items.Length || items[position] == null) { return false; } else { return true; } } public object Next() { MenuItem menuItem = items[position] as MenuItem; position = position + 1; return menuItem; } } public interface IMenu { Iterator CreateIterator(); } }
迭代器模式主要是聚合对象创建迭代器,借助单一职责的原则,从而实现客户端可以对聚合的各种对象实现相同的操作,达到代码复用的效果。
1.3迭代器模式类图
下面看看上面代码的类图,
然后再看看迭代器模式的类图。
二、组合模式
2.1组合模式定义
组合模式允许将对象组合成属性结构来表现“整体/部分”层次结构,组合能让客户以一致的方式处理个别对象以及对象组合。
2.2组合模式例子
下面是组合模式的例子:
class Program { static void Main(string[] args) { //定义早餐==================================================================== MenuComponent menu = new Menu("早餐", "新鲜的早餐"); MenuComponent menuItem1 = new MenuItem("牛奶", "牛奶description", false, 3.0); MenuComponent menuItem2 = new MenuItem("油条", "油条description", false, 1.0); MenuComponent menuItem3 = new MenuItem("馒头", "馒头description", true, 1.0); MenuComponent menuItem4 = new MenuItem("豆浆", "DoujiangDescription", true, 1.5); menu.Add(menuItem1); menu.Add(menuItem2); menu.Add(menuItem3); menu.Add(menuItem4); //定义午餐==================================================================== MenuComponent lunch = new Menu("午餐", "包括下午茶"); MenuComponent lunch1=new MenuItem("香菇豆腐饭", "香菇豆腐", false, 10.5); MenuComponent lunch2 = new MenuItem("蛋炒饭", "哈哈", false, 8.5); MenuComponent lunch3 = new MenuItem("鱼香肉丝", "你猜", true, 15.5); MenuComponent tea = new Menu("下午茶", "新鲜的下午茶"); MenuComponent tea1 = new MenuItem("香蕉片", "香蕉片", true, 10); MenuComponent tea2 = new MenuItem("咖啡", "大杯的哦", true, 10); tea.Add(tea1); tea.Add(tea2); lunch.Add(lunch1); lunch.Add(lunch2); lunch.Add(lunch3); lunch.Add(tea); //定义三餐==================================================================== MenuComponent food = new Menu("三餐", "三餐列表"); food.Add(menu); food.Add(lunch); food.Print(); Console.ReadKey(); } } /// <summary> /// 菜单组件 /// </summary> public abstract class MenuComponent { public abstract void Add(MenuComponent menucomponent); public abstract void Remove(MenuComponent menucomponent); public abstract MenuComponent GetChild(int i); public abstract string GetDescription(); public abstract string GetName(); public abstract double GetPrice(); public abstract bool IsVegetarian(); public abstract void Print(); } public class MenuItem:MenuComponent { private string name; private string description; private bool vegetarin; private double price; public MenuItem(string name, string description, bool vegetarin, double price) { this.name = name; this.description = description; this.vegetarin = vegetarin; this.price = price; } public override string GetName() { return name; } public override double GetPrice() { return price; } public override bool IsVegetarian() { return vegetarin; } public override string GetDescription() { return description; } public override void Print() { Console.Write(""+GetName()+","); if (IsVegetarian()) { Console.Write("(素) ,"); } Console.Write(GetPrice()+"¥,"); Console.WriteLine(GetDescription()+"。"); } public override MenuComponent GetChild(int i) { throw new NotImplementedException(); } public override void Add(MenuComponent menucomponent) { throw new NotImplementedException(); } public override void Remove(MenuComponent menucomponent) { throw new NotImplementedException(); } } public class Menu : MenuComponent { ArrayList menuComponents = new ArrayList(); private string name; private string description; public Menu(string name, string description) { this.name = name; this.description = description; } public override void Add(MenuComponent menucomponent) { menuComponents.Add(menucomponent); return; } public override void Remove(MenuComponent menucomponent) { menuComponents.Remove(menucomponent); } public override string GetName() { return name; } public override string GetDescription() { return description; } public override void Print() { Console.Write("--"+GetName()); Console.WriteLine("," + GetDescription()); IEnumerator enumerator = menuComponents.GetEnumerator(); while (enumerator.MoveNext()) { MenuComponent menuComponent = (MenuComponent)enumerator.Current; menuComponent.Print(); } } public override MenuComponent GetChild(int i) { throw new NotImplementedException(); } public override double GetPrice() { throw new NotImplementedException(); } public override bool IsVegetarian() { throw new NotImplementedException(); } }
相关推荐
在这个主题中,我们主要探讨了如何利用组合模式(Composite Pattern)构建二叉树,并通过迭代器模式(Iterator Pattern)来实现对树的遍历,包括前序、中序和后序遍历。这些是设计模式中的经典应用,对于理解和掌握...
在实际应用中,迭代器模式常用于各种容器(如数组、链表、树等)的遍历,以及模板方法模式、策略模式等设计模式的组合。例如,在Java的`Collections`类中,有许多方法(如`sort()`、`shuffle()`)都依赖于迭代器来...
- 组合模式与其他设计模式(如装饰器模式、代理模式等)的区别和结合使用。 在使用组合模式时,我们需要注意: - 避免在客户端代码中直接依赖于具体类,而是依赖于组件接口,以保持代码的灵活性和可扩展性。 - 为了...
迭代器模式(Iterator Pattern)和组合模式(Composite Pattern)是设计模式中的两种重要结构型模式,它们在软件设计中有着广泛的应用。这两种模式都属于GoF(Gang of Four)设计模式,旨在解决特定的问题,提升代码...
这份文档以例子的形式讲诉了设计模式之迭代器与组合模式,希望可以帮助学习的人!
### Java 23种设计模式之迭代器模式 #### 模式动机与定义 迭代器模式(Iterator Pattern)是设计模式中的一种行为型模式,它主要用于处理聚合对象(如列表、集合等)。此模式的核心目的是提供一种方法来访问聚合...
3. **迭代器模式**:迭代器模式是行为型设计模式,它允许我们遍历集合对象的元素而无需暴露其底层表示。迭代器模式提供了一种方法顺序访问聚合对象中的元素,而无需暴露其底层结构。在Java中,迭代器模式广泛应用于...
Java内置了对迭代器模式的支持,其中java.util.Enumeration和java.util.Iterator接口就是迭代器接口。Java的许多聚合类,如sets、lists、maps和vector,都实现了这些接口,以提供统一的遍历方法。 迭代器模式的适用...
《HeadFirst JAVA设计模式》中利用迭代器迭代组合模式存在错误,课本中实现代码对于大于两层的树状测试数据存在错误(即Menu里有Menu),这里给出原错误测试代码(compositeIter包)和错误解决代码(solveIter包)。
PPT内容包括:内附代码,...设计模式13-迭代器模式 设计模式14-中介者模式、备忘录模式 设计模式15-观察者模式、状态模式 设计模式16-策略模式、模板方法、访问者 此PPT实例便于理解,对于深入理解OO思想有很大帮助。
<!-- TOC --> - 23种设计模式 - 工厂方法模式(Factory Method) - 抽象工厂模式(Abstract Factory) - 单例模式(Singleton) - 建造者模式(Builder)... - 迭代器模式(Iterator) - 备忘录模式(Memento) - 状态模式(S
在这个话题中,我们将深入探讨如何利用组合模式(Composite Pattern)和迭代模式(Iterator Pattern)来构建和遍历树结构。 **组合模式**是面向对象设计模式的一种,它允许我们处理部分和整体的关系。在树形结构中...
内容包括统一建模语言基础知识、面向对象设计原则、设计模式概述、简单工厂模式、工厂方法模式、抽象工厂模式、建造者模式、原型模式、单例模式、适配器模式、桥接模式、组合模式、装饰模式、外观模式、享元模式、...
迭代器模式 命令模式 职责链模式 进来者模式 访问者模式 数据结构 Stack - 使用泛型实现Stack 生成斐波那契数列 使用容器 利用迭代器实现原材料 实用程序 StringUtil类 - 封装常用的String方法 基本的 正则表达式的...
- 迭代器模式 - 代理模式 - 适配器模式 2. 设计模式的基本要素: - 名字 - 意图 - 问题 - 解决方案 - 参与者与协作者 - 实现 - 一般性构造 3. 设计模式的应用场景: - 使用命令模式来参数化客户请求 -...
4. **迭代器模式与其他模式的交互**:讨论迭代器模式如何与工厂模式、组合模式等其他设计模式结合使用,以增强系统的灵活性和扩展性。 5. **实例分析**:通过具体的C#代码示例展示如何实现和使用迭代器模式,可能...
行为型模式(策略模式、 迭代器模式、原型模式、职责链模式、 模板方法、 命令模式、 解释器模式、 中介者模式、 访问者模式、 状态模式、 备忘录模式); 结构型模式(代理模式、桥接模式、适配器模式、外观模式、...
以上只是C# 3.0设计模式的一小部分,实际应用中还包括适配器模式、迭代器模式、组合模式等。通过理解和熟练运用这些设计模式,开发者可以编写出更具弹性和可维护性的代码,以适应不断变化的需求。而"《C# 3.0设计...
迭代器模式提供一种方法顺序访问聚合对象的元素,而又不暴露其底层表示。Java集合框架中的Iterator接口就是迭代器模式的体现。 十六、状态模式 状态模式允许对象在其内部状态改变时改变其行为,对象看起来好像修改...
在给定的标题和描述中,提到了三种特定的设计模式:组合模式、公司管理系统以及迭代器模式。让我们深入探讨这三种模式以及它们在Java编程中的应用。 1. **组合模式**: 组合模式是一种结构型设计模式,它允许我们...