设计模式C#实现(四)——迭代器模式
迭代器模式:提供一种方法顺序访问一个聚合对象中的各个元素,而又不暴露其内部的表示。
UML类图:

煎饼屋和餐厅合并了!但是有个小问题,虽然两家都同意实现相同的菜单项MenuItem,但是煎饼屋想使用ArrayList储存菜单项,而餐厅则使用数组,为了使女招待能同时访问两家的菜单,我们需要为菜单提供一个统一的访问接口。
先来看菜单项MenuItem,两家店的实现相同
class MenuItem
{
string name;//名称
string description;//描述
bool vegetarian;//是否是素食
double price;//价格 public MenuItem(string name, string description, bool vegetarian, double price)
{
this.name = name;
this.description = description;
this.vegetarian = vegetarian;
this.price = price;
} public string getName()
{
return name; }
public string getDescription()
{
return description;
}
public double getPrice()
{
return price;
}
public bool isVegetarian()
{
return vegetarian;
} }
接口Menu,它只定义了一个创建迭代器的方法,实现这个接口的类将提供各自不同的迭代器
interface Menu
{
Iterator createIterator();
}
煎饼屋菜单,实现了Menu接口
class PancakeHouseMenu : Menu
{
ArrayList menuItems;
public PancakeHouseMenu()
{
menuItems = new ArrayList();
addItem("K&B's Pancake Breakfast", "Pancakes with scrambled eggs,and toast", true, 2.99);
addItem("Regular Pancake Breakfast", "Pancakes with fired eggs,and sausage", false, 2.99);
addItem("Blueberry Pancake", "Pancakes with fresh blueberries", true, 3.49);
addItem("Waffles", "Waffles,with your choice of blueberries or strawberries", true, 3.59); }
public void addItem(string name, string description, bool vegetarian, double price)
{
MenuItem menuItem = new MenuItem(name, description, vegetarian, price);
menuItems.Add(menuItem);
} public Iterator createIterator()
{
return new PancakeHouseIterator(menuItems);
}
//菜单的其他方法
}
餐厅菜单同样如此
class DinerMenu : Menu
{
static int Max_ITEMS = ;
int numberOfItems = ;
MenuItem[] menuItems;
public DinerMenu()
{
menuItems = new MenuItem[Max_ITEMS];
addItem("Vegetarian BLT", "(Fakin') Bacon with lettuce & tomato on whole wheat", true, 2.99);
addItem("BLT", "Bacon with lettuce & tomato on whole wheat", false, 2.99);
addItem("Soup of the day", "Soup of the day,whit a side of potato salad", false, 3.29);
addItem("Hot dog", "A hot dog, with saurkraut, relish, onions, topped with cheese", false, 3.05); }
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("Sorry,menu is full! Can't add item to menu!");
}
else
{
menuItems[numberOfItems] = menuItem;
numberOfItems++;
}
}
public MenuItem[] getMenuItems()
{
return menuItems;
}
public Iterator createIterator()
{
return new DinerMenuIterator(menuItems);
}
//菜单的其他方法
}
接下来看看迭代器,迭代器有一个接口,定义了一些操作
interface Iterator
{
bool hasNext();
object next();
//更多的方法,例如remove...
}
不同的菜单有不同的迭代器,这是煎饼屋的
class PancakeHouseIterator:Iterator
{
ArrayList items;
int position = ;
public PancakeHouseIterator(ArrayList items)
{
this.items = items;
}
public object next()
{
MenuItem menuItem = (MenuItem)items[position];
position++;
return menuItem;
}
public bool hasNext()
{
if (position>=items.Count)
{
return false;
}
else
{
return true;
}
}
}
这是餐厅的
class DinerMenuIterator:Iterator
{
MenuItem[] items;
int position = ;
public DinerMenuIterator(MenuItem[] items)
{
this.items = items;
}
public object next()
{
MenuItem menuItem = items[position];
position++;
return menuItem;
}
public bool hasNext()
{
if (position>=items.Length||items[position]==null)
{
return false;
}
else
{
return true;
}
}
}
选择女招待可以方便的用统一的方法操作两家的菜单了
class Waitress
{
Menu pancakeHouseMenu;
Menu dinerMenu;
public Waitress(Menu pancake, Menu diner)
{
this.pancakeHouseMenu = pancake;
this.dinerMenu = diner;
}
public void printMenu()
{
Iterator pancakeIterator = pancakeHouseMenu.createIterator();
Iterator dinerIterator = dinerMenu.createIterator();
Console.WriteLine("MENU\n----\nBREAKFAT");
printMenu(pancakeIterator);
Console.WriteLine("\nLUNCH");
printMenu(dinerIterator);
}
private void printMenu(Iterator iterator)
{
while (iterator.hasNext())
{
MenuItem menuItem = (MenuItem)iterator.next();
Console.Write(menuItem.getName() + ",");
Console.WriteLine(menuItem.getPrice() + "-- ");
Console.WriteLine(" "+menuItem.getDescription());
}
}
}
迭代器的好处是将来如果有新的菜单加入,而它使用了不同的存储方法(例如hashtable),只需要让它实现迭代器接口,而不必修改女招待的操作方式。
设计模式C#实现(四)——迭代器模式的更多相关文章
- 设计模式 ( 十四 ) 迭代器模式Iterator(对象行为型)
设计模式 ( 十四 ) 迭代器模式Iterator(对象行为型) 1.概述 类中的面向对象编程封装应用逻辑.类,就是实例化的对象,每个单独的对象都有一个特定的身份和状态.单独的对象是一种组织代码的 ...
- Javascript设计模式之我见:迭代器模式
大家好!本文介绍迭代器模式及其在Javascript中的应用. 模式介绍 定义 提供一种方法顺序一个聚合对象中各个元素,而又不暴露该对象内部表示. 类图及说明 Iterator抽象迭代器 抽象迭代器负 ...
- 《Head first设计模式》学习笔记 – 迭代器模式
<Head first设计模式>学习笔记 – 迭代器模式 代器模式提供一种方法顺序访问一个聚合对象中的各个元素,而又不暴露其内部的表示. 爆炸性新闻:对象村餐厅和对象村煎饼屋合并了!真是个 ...
- C#设计模式之十六迭代器模式(Iterator Pattern)【行为型】
一.引言 今天我们开始讲"行为型"设计模式的第三个模式,该模式是[迭代器模式],英文名称是:Iterator Pattern.还是老套路,先从名字上来看看."迭代器模 ...
- C#设计模式之十五迭代器模式(Iterator Pattern)【行为型】
一.引言 今天我们开始讲“行为型”设计模式的第三个模式,该模式是[迭代器模式],英文名称是:Iterator Pattern.还是老套路,先从名字上来看看.“迭代器模式”我第一次看到这个名称,我的理解 ...
- C#设计模式(15)——迭代器模式
1.迭代器模式介绍 迭代器模式主要用于遍历聚合对象,将聚合对象的遍历行为分离出来,抽象为一个迭代器来负责.迭代器模式用的十分普遍,C#/JAVA等高级语言都对迭代器进行了封装用于遍历数组,集合,列表等 ...
- 设计模式17:Iterator 迭代器模式(行为型模式)
Iterator 迭代器模式(行为型模式) 动机(Motivation) 在软件构建过程中,集合对象内部结构常常变化各异.但对于这些集合对象,我们希望在不暴露其内部结构的同时,可以让外部客户代码可以透 ...
- 设计模式-(12)迭代器模式 (swift版)
一,概念 迭代器模式(Iterator Pattern)是 Java 和 .Net 编程环境中非常常用的设计模式.这种模式用于顺序访问集合对象的元素,不需要知道集合对象的底层表示.迭代器模式属于行为型 ...
- Delphi 设计模式:《HeadFirst设计模式》Delphi7代码---迭代器模式之DinerMenu[转]
容器的主要职责有两个:存放元素和浏览元素.根据单一职责原则(SRP)要将二者分开,于是将浏览功能打包封装就有了迭代器. 用迭代器封装对动态数组的遍历: 1 2{<HeadFirst设计模式& ...
随机推荐
- P6 EPPM R16.1安装与配置指南(二)
P6 EPPM R16.1安装与配置指南(一) http://www.cnblogs.com/endv/p/5634620.html P6 EPPM R16.1安装与配置指南(二) 环境变量配置 新建 ...
- 使用win2d实现萤火虫粒子效果
这几天我在做游戏的标题画面,需要实现随机飞舞的萤火虫.萤火虫会闪烁黄绿色的光,远近不同,并且飞出屏幕边界不久会自动飞回来. 我前一阵子用win2d写了个简单的游戏引擎(现在还是alpha阶段),用它可 ...
- *nix下传统编程入门之GCC
准备工作 注意:本文可能会让你失望,如果你有下列疑问的话:为什么要在终端输命令啊? GCC 是什么东西,怎么在菜单中找不到? GCC 不能有像 VC 那样的窗口吗?…… 那么你真正想要了解的可能是 a ...
- 从零开始学习Linux(ls命令)
学习Linux已经两年了,可是仍然是小白一个.用过很多命令,可是很多都没记住,基础不扎实,很大程度上是不记笔记,得过且过. 从今天起,开始整理Linux笔记. Linux每个命令都有--help这个选 ...
- JavaScript来实现打开链接页面(转载)
在页面中的链接除了常规的方式以外,如果使用javascript,还有很多种方式,下面是一些使用javascript,打开链接的几种方式: 1.使用window的open方法打开链接,这里可是在制定页面 ...
- php面试题之一——PHP核心技术(高级部分)
一.PHP核心技术 1.写出一个能创建多级目录的PHP函数(新浪网技术部) <?php /** * 创建多级目录 * @param $path string 要创建的目录 * @param $m ...
- java响应微信用户信息(wechat4j)
你的微信应用程序接收到用户发送的消息事件之后,可以进行响应.wechat4j支持多种消息的响应. wechat4j响应消息的部分在wechat4j的入口WechatSupport.java中定义,直接 ...
- mvc项目架构分享系列之架构搭建之Repository和Service
项目架构搭建之Repository和Service的搭建 Contents 系列一[架构概览] 0.项目简介 1.项目解决方案分层方案 2.所用到的技术 3.项目引用关系 系列二[架构搭建初步] 4. ...
- offset笔记
1.offsetParent 2.offsetTop 3.offsetLeft 4.offsetWidth 5.offsetHeight offsetWidth是元素的可视宽度,这个宽度包括元素的边框 ...
- Mybatis学习记录(七)----Mybatis查询缓存
1. 什么是查询缓存 mybatis提供查询缓存,用于减轻数据压力,提高数据库性能. mybaits提供一级缓存,和二级缓存. 一级缓存是SqlSession级别的缓存.在操作数据库时需要构造 sql ...