JAVA设计模式——迭代器模式
来源:互联网 发布:21端口被占用 编辑:程序博客网 时间:2024/06/10 05:06
迭代器模式
提供一种方法顺序访问一个聚合对象中的各个元素,而又不暴露其内部的表示。
迭代器模式把在元素之间游走的责任交给了迭代器,而不是聚合对象。这不仅让聚合的接口和实现变得更简洁,也可以让聚合更专注在它所应该专注的事情上面(也就是管理对象集合),而不必去理会遍历的事情。
下面是具体例子:
菜单项的类:MenuItem.java
- package com.designpattern.iterator;
- public class MenuItem {
- String name;
- String description;
- boolean vegetarian;
- double price;
- public MenuItem(String name,
- String description,
- boolean 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 boolean isVegetarian() {
- return vegetarian;
- }
- public double getPrice() {
- return price;
- }
- }
菜单的共同接口(用于返回迭代器):Menu.java
- package com.designpattern.iterator;
- import java.util.Iterator;
- /**
- * 菜单的共同接口
- * */
- public interface Menu {
- public Iterator<?> createIterator();
- }
建立两个菜单:PancakeHouseMenu.java & DinerMenu.java,都实现Menu接口
- package com.designpattern.iterator;
- import java.util.ArrayList;
- import java.util.Iterator;
- /**
- * 用ArrayList来存储菜单项,有内嵌的返回迭代器方法,menuItems.iterator();
- * createIterator()方法中可以直接返回迭代器,不用自己写迭代器;
- * */
- public class PancakeHouseMenu implements Menu{
- ArrayList<MenuItem> menuItems;
- public PancakeHouseMenu(){
- menuItems = new ArrayList<MenuItem>();
- addItem("K&B's 薄煎饼早餐", "薄煎饼、清蛋和吐司", true, 2.99);
- addItem("薄煎饼早餐例餐", "薄煎饼带煎蛋,香肠", false, 2.99);
- addItem("蓝莓薄煎饼", "新鲜蓝莓和蓝莓糖浆做成的薄煎饼", true, 3.49);
- addItem("松饼", "松饼,可以选择蓝莓或草莓", true, 3.59);
- }
- public void addItem(String name, String description,
- boolean vegetarian, double price){
- MenuItem menuItem = new MenuItem(name, description, vegetarian, price);
- menuItems.add(menuItem);
- }
- // public ArrayList<MenuItem> getMenuItems(){
- // return menuItems;
- // }
- @Override
- public Iterator<MenuItem> createIterator() {
- // TODO Auto-generated method stub
- return menuItems.iterator();
- }
- }
- package com.designpattern.iterator;
- import java.util.Iterator;
- /**
- * 用数组来存储菜单项,没有内嵌的返回迭代器方法;
- * 需要自己写迭代器:DinerMenuIterator.java,继承自Iterator类。
- * */
- public class DinerMenu implements Menu{
- static final int MAX_ITEMS = 6;
- int numberOfItems = 0;
- MenuItem[] menuItems;
- public DinerMenu(){
- menuItems = new MenuItem[MAX_ITEMS];
- addItem("素食BLT", "(煎)培根、生菜&西红柿,用麦皮面包做", true, 2.99);
- addItem("BLT", "培根、生菜&西红柿", false, 2.99);
- addItem("例汤", "一碗例汤,配土豆沙拉", false, 3.29);
- addItem("热狗", "热狗、酸菜、上盖芝士", false, 3.05);
- }
- public void addItem(String name,String description,
- boolean vegetarian, double price){
- MenuItem menuItem = new MenuItem(name, description, vegetarian, price);
- if(numberOfItems >= MAX_ITEMS){
- System.err.println("Sorry, menu is full! Can't add item to menu.");
- }else{
- menuItems[numberOfItems] = menuItem;
- numberOfItems +=1;
- }
- }
- // public MenuItem[] getMenuItems(){
- // return menuItems;
- // }
- @Override
- public Iterator<Object> createIterator() {
- // TODO Auto-generated method stub
- return new DinerMenuIterator(menuItems);
- }
- }
DinerMenu.java中用到的返回迭代器的类:DinerMenuIterator.java
- package com.designpattern.iterator;
- import java.util.Iterator;
- /**
- * 由于数组没有内嵌的返回迭代器的方法,因此需要写自己的迭代器;
- * */
- public class DinerMenuIterator implements Iterator<Object>{
- MenuItem[] list;
- int position = 0;
- public DinerMenuIterator(MenuItem[] list){
- this.list = list;
- }
- @Override
- public boolean hasNext() {
- // TODO Auto-generated method stub
- if(position >= list.length || list[position] == null){
- return false;
- }else{
- return true;
- }
- }
- @Override
- public Object next() {
- // TODO Auto-generated method stub
- MenuItem menuItem = list[position];
- position += 1;
- return menuItem;
- }
- @Override
- public void remove() {
- // TODO Auto-generated method stub
- if(position <= 0){
- throw new IllegalStateException("You can't remove an item until you've done at least one next().");
- }
- if(list[position - 1] != null){
- for(int i = position-1;i<(list.length -1);i++){
- list[i] = list[i+1];
- }
- list[list.length-1] = null;
- }
- }
- }
具体操作菜单的类:Waitress.java
- package com.designpattern.iterator;
- import java.util.Iterator;
- /**
- * 操作菜单的类
- * */
- public class Waitress {
- Menu pancakeHouseMenu;
- Menu dinerMenu;
- public Waitress(Menu pancakeHouseMenu, Menu dinerMenu){
- this.pancakeHouseMenu = pancakeHouseMenu;
- this.dinerMenu = dinerMenu;
- }
- public void printMenu(){
- Iterator<?> pancakeIterator = pancakeHouseMenu.createIterator();
- Iterator<?> dinerIterator = dinerMenu.createIterator();
- System.out.println("MENU\n----\nBREAKFAST");
- printMenu(pancakeIterator);
- System.out.println("\nLUNCH");
- printMenu(dinerIterator);
- }
- private void printMenu(Iterator<?> iterator){
- while(iterator.hasNext()){
- MenuItem menuItem = (MenuItem) iterator.next();
- System.out.println(menuItem.getName() + ",");
- System.out.println(menuItem.getPrice() + "---");
- System.out.println(menuItem.getDescription());
- }
- }
- }
测试类:Test.java
- package com.designpattern.iterator;
- public class Test {
- public static void main(String[] args) {
- Menu pancakeHouseMenu = new PancakeHouseMenu();
- Menu dinerMenu = new DinerMenu();
- Waitress waitress = new Waitress(pancakeHouseMenu, dinerMenu);
- waitress.printMenu();
- }
- }
两个菜单都实现了Menu接口,Waitress类可以直接利用接口引用每一个菜单对象。这样通过“针对接口编程,而不是针对实现编程”,我们就可以减少Waitress类与具体类之间的依赖。
此外,如果想要再添加新的菜单也会变得很容易,只需要按照前面两个菜单类写一个继承Menu接口的菜单类,再在Waitress类中添加菜单类的对象即可。即Waitress类具有更好的扩展性。
JAVA 5包含了一种新形式的for语句,称for/in。这可以让你在一个集合或者一个数组中遍历,而且不需要显式创建迭代器。但需要使用JAVA 5的泛型新特性来确保for/in的类型安全。
但是,迭代器模式还存在一个问题,假如想在菜单中添加子菜单,迭代器模式是不可以实现的。
0 0
- JAVA设计模式——迭代器模式
- java设计模式——迭代器模式
- JAVA设计模式——迭代器模式
- JAVA设计模式——迭代器模式
- Java设计模式——迭代器模式
- java设计模式——迭代器模式
- JAVA设计模式—迭代器模式(Iterator)
- java设计模式—迭代器模式
- JAVA设计模式——组合模式+迭代器模式
- Java设计模式—解释器模式&迭代器模式简介
- Java设计模式—工厂设计模式
- java设计模式——代理模式
- JAVA设计模式——工厂模式
- Java设计模式——观察者模式
- Java设计模式——组合模式
- Java设计模式——命令模式
- JAVA设计模式——命令模式
- JAVA设计模式——适配器模式
- 实现算法2.17的程序
- 南阳 585 取石子(六)(尼姆博弈)
- python编码错误:UnicodeEncodeError: ‘ascii’ codec can’t encode characters in position xxx ordinal not in
- linux信号量
- 一个数组中可根据需要生成若干个独立的链表
- JAVA设计模式——迭代器模式
- 南阳 161 取石子 (四)(威佐夫博弈)
- 内存管理初级
- NSPredicate 小结 &正则表达式
- release为什么不能用
- 实现算法2.15、2.16的程序(一个数组只生成一个静态链表)
- hdoj 3787 A+B 水过~
- FOUR组第四周总结
- UNIX网络编程 - UNIX errno值