`
youyu4
  • 浏览: 451461 次
社区版块
存档分类
最新评论

迭代器模式和组合模式---转

 
阅读更多

把迭代器模式和组合模式放在同一篇的原因是其联系比较紧密。

一、迭代器模式

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迭代器模式类图

下面看看上面代码的类图,

image

然后再看看迭代器模式的类图。

image

二、组合模式

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(); 
        } 
    }
复制代码

image

 

 

 

原文:http://www.cnblogs.com/lzhp/p/3427704.html

分享到:
评论

相关推荐

    组合模式二叉树,前序、中序、后续,迭代器模式访问遍历

    在这个主题中,我们主要探讨了如何利用组合模式(Composite Pattern)构建二叉树,并通过迭代器模式(Iterator Pattern)来实现对树的遍历,包括前序、中序和后序遍历。这些是设计模式中的经典应用,对于理解和掌握...

    迭代器模式(Iterator Pattern)详解 1. 什么是迭代器模式? 2. 为什么需要迭代器模式? 3. 迭代器模式的核心概念 3.1 迭代器(Iterator) 3.2 具体迭代器(Conc

    8.2 迭代器模式 vs 组合模式 8.3 迭代器模式 vs 模板方法模式 9. 迭代器模式的优缺点 9.1 优点 9.2 缺点 10. 何时使用迭代器模式? 11. 常见问题与解决方案 11.1 如何避免迭代器泄露内部结构? 11.2 如何处理迭代...

    设计模式之迭代器模式(Iterator)

    在实际应用中,迭代器模式常用于各种容器(如数组、链表、树等)的遍历,以及模板方法模式、策略模式等设计模式的组合。例如,在Java的`Collections`类中,有许多方法(如`sort()`、`shuffle()`)都依赖于迭代器来...

    组合模式-------树形模式

    - 组合模式与其他设计模式(如装饰器模式、代理模式等)的区别和结合使用。 在使用组合模式时,我们需要注意: - 避免在客户端代码中直接依赖于具体类,而是依赖于组件接口,以保持代码的灵活性和可扩展性。 - 为了...

    Head First 设计模式 (九) 迭代器与组合模式(Iterator & Composite pattern) C++实现

    迭代器模式(Iterator Pattern)和组合模式(Composite Pattern)是设计模式中的两种重要结构型模式,它们在软件设计中有着广泛的应用。这两种模式都属于GoF(Gang of Four)设计模式,旨在解决特定的问题,提升代码...

    设计模式之迭代器与组合模式

    这份文档以例子的形式讲诉了设计模式之迭代器与组合模式,希望可以帮助学习的人!

    Java 23种设计模式20迭代器模式.pdf

    ### Java 23种设计模式之迭代器模式 #### 模式动机与定义 迭代器模式(Iterator Pattern)是设计模式中的一种行为型模式,它主要用于处理聚合对象(如列表、集合等)。此模式的核心目的是提供一种方法来访问聚合...

    JAVA 设计模式 工厂模式 代理模式 迭代模式 责任链模式 源码

    3. **迭代器模式**:迭代器模式是行为型设计模式,它允许我们遍历集合对象的元素而无需暴露其底层表示。迭代器模式提供了一种方法顺序访问聚合对象中的元素,而无需暴露其底层结构。在Java中,迭代器模式广泛应用于...

    2 迭代器模式-MOOC课程内容.pdf

    Java内置了对迭代器模式的支持,其中java.util.Enumeration和java.util.Iterator接口就是迭代器接口。Java的许多聚合类,如sets、lists、maps和vector,都实现了这些接口,以提供统一的遍历方法。 迭代器模式的适用...

    HeadFirst 组合模式+迭代器错误原因以及解决代码

    《HeadFirst JAVA设计模式》中利用迭代器迭代组合模式存在错误,课本中实现代码对于大于两层的树状测试数据存在错误(即Menu里有Menu),这里给出原错误测试代码(compositeIter包)和错误解决代码(solveIter包)。

    设计模式课件大全

    PPT内容包括:内附代码,...设计模式13-迭代器模式 设计模式14-中介者模式、备忘录模式 设计模式15-观察者模式、状态模式 设计模式16-策略模式、模板方法、访问者 此PPT实例便于理解,对于深入理解OO思想有很大帮助。

    java版本二十三种设计模式.zip

    &lt;!-- TOC --&gt; - 23种设计模式 - 工厂方法模式(Factory Method) - 抽象工厂模式(Abstract Factory) - 单例模式(Singleton) - 建造者模式(Builder)... - 迭代器模式(Iterator) - 备忘录模式(Memento) - 状态模式(S

    树的构件与遍历---使用组合模式与迭代模式

    在这个话题中,我们将深入探讨如何利用组合模式(Composite Pattern)和迭代模式(Iterator Pattern)来构建和遍历树结构。 **组合模式**是面向对象设计模式的一种,它允许我们处理部分和整体的关系。在树形结构中...

    《Java设计模式》电子课件01至21章(程细柱PDF)

    内容包括统一建模语言基础知识、面向对象设计原则、设计模式概述、简单工厂模式、工厂方法模式、抽象工厂模式、建造者模式、原型模式、单例模式、适配器模式、桥接模式、组合模式、装饰模式、外观模式、享元模式、...

    【资源免费下载】Java代码积累丨大话设计模式(Java实现版本)、线程协作

    迭代器模式 命令模式 职责链模式 进来者模式 访问者模式 数据结构 Stack - 使用泛型实现Stack 生成斐波那契数列 使用容器 利用迭代器实现原材料 实用程序 StringUtil类 - 封装常用的String方法 基本的 正则表达式的...

    设计模式复习题.doc

    - 迭代器模式 - 代理模式 - 适配器模式 2. 设计模式的基本要素: - 名字 - 意图 - 问题 - 解决方案 - 参与者与协作者 - 实现 - 一般性构造 3. 设计模式的应用场景: - 使用命令模式来参数化客户请求 -...

    23种设计模式详解PDF

    适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元模式。 行为型模式(11): 策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、...

    GOF-设计模式-Design Patterns-英文原版-高清-有目录-有页码

    本书还附带了一些基础类库的介绍,例如列表(List)、迭代器(Iterator)、列表迭代器(ListIterator)、点(Point)、矩形(Rect)等,这些都是在实现设计模式时常用的数据结构。 #### 十一、参考文献与索引 **参考文献与...

    C#面向对象设计模式纵横谈-行为模式(合集)

    4. **迭代器模式与其他模式的交互**:讨论迭代器模式如何与工厂模式、组合模式等其他设计模式结合使用,以增强系统的灵活性和扩展性。 5. **实例分析**:通过具体的C#代码示例展示如何实现和使用迭代器模式,可能...

    C#23种设计模式样例代码和UML图

    行为型模式(策略模式、 迭代器模式、原型模式、职责链模式、 模板方法、 命令模式、 解释器模式、 中介者模式、 访问者模式、 状态模式、 备忘录模式); 结构型模式(代理模式、桥接模式、适配器模式、外观模式、...

Global site tag (gtag.js) - Google Analytics