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

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

 
阅读更多

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

一、迭代器模式

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模式构成二叉树,并用迭代器模式封装访问,前序、中序和后序的遍历。JAVA 编写。 Main中直接运行

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

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

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

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

    设计模式(JAVA语言实现)--20种设计模式附带源码PPT模板.pptx

    logo 16迭代器模式:定义迭代器和聚集接口迭代器模式:定义迭代器和聚集接口 设计模式(JAVA语言实现)--20种设计模式附带源码PPT模板全文共22页,当前为第17页。 logo 17责任链模式:定义接口、抽象类责任链模式:...

    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

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

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

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

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

    设计模式-C++

    结构型模式,共七种:适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元模式。 行为型模式,共十一种:策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、...

    java设计模式之禅

    以简单、诙谐幽默的例子讲述面向对象设计中的23中设计模式。策略模式、观察者模式、单例模式、工厂方法、抽象工厂、迭代器模式、状态模式、适配器模式、装饰者模式、组合模式、原型模式、模板方法……

    java 23种设计模式.zip

    设计模式主要分为三大类: 1.创建型模式:工厂模式、抽象...4.行为型模式:模板方法模式、命令模式、迭代器模式、观察者模式、中介者模式、备忘录模式、解释器模式、状态模式、策略模式、职责链模式、访问者模式。

    05-容易被忽略的迭代器(1).html

    组合模式( Composite ) 享元模式( Flyweight ) 行为型模式包含了: 策略模式( Strategy ) 模板方法模式( Template Method ) 观察者模式( Observer ) 迭代子模式( Iterator ) 责任链模式( Chain of ...

    软件设计模式与体系结构(讲解+代码)

     【例3.2】组合模式-五子棋代码  【例3.3】组合模式-空军指挥系统  【例3.4】组合模式-世界问候语  【例3.7】类适配器模式-客户信息验证  【例3.8】对象适配器模式-字符串排序  【例3.10】外观模式-安全...

    23种设计模式 -设计模式图解.7z

    结构型模式,共七种:适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元模式。 行为型模式,共十一种:策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、...

    java中的设计模式,主要的设计模式

    适配器模式、装饰者模式、代理模式、外观模式、桥接模式、组合模式、享元模式观察者模式、策略模式、模板模式、责任链模式、解析器模式、迭代子模式 命令模式、状态模式、备忘录模式、访问者模式、中介者模式

    design-pattern-java.pdf

    桥接模式-Bridge Pattern 处理多维度变化——桥接模式(一) 处理多维度变化——桥接模式(二) 处理多维度变化——桥接模式(三) 处理多维度变化——桥接模式(四) 组合模式-Composite Pattern 树形结构的处理...

    设计模式自己总结一句话描述

    行为型模式,共十一种: 策略模式、模板方法模式、观察者模式、迭代器模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式。 其实还有两类:并发型模式和线程池模式。

    Java23种设计模式可直接运行Demo

    结构型模式,共七种:适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元模式。 行为型模式,共十一种:策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、...

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

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

Global site tag (gtag.js) - Google Analytics