《Head.First设计模式》的学习笔记(12)--迭代器模式



  意图:
提供一种方法顺序访问一个聚合对象中的各个元素,而又不暴露其内部的表现。

 结构:

 

 

让我们看一下一个例子:

对乡村的餐厅和对象村的煎饼屋合并了。现在碰到一个棘手的问题,餐厅的菜单是使用Arraylist来实现,而煎饼屋的菜单是用数组来进行实现的,由于各自的菜单已经与其他过多的代码进行耦合,所以不能进行更改,现在有一个女Waitress,需要打印全部菜单,我们最初设想就是去分别遍历各自的菜单,但是如果添加以后我们需要第三种遍历方式。。

我们来看这样的缺点:

1.重复代码过多,都是过多的循环遍历,虽然每种遍历方式不同。

2.将菜单的实现暴露在外,耦合过高。

现在我们来看,按照上述结构我们画出的类图如下:



 下面我们具体看一下代码,煎饼屋的代码:

首先是Inteactor接口我们使用java的api自带的:



 然后我们来看煎饼屋的午餐迭代器的实现:

import java.util.Iterator;
  
public class DinerMenuIterator implements Iterator {
	MenuItem[] list;
	int position = 0;
 
	public DinerMenuIterator(MenuItem[] list) {
		this.list = list;
	}
 
	public Object next() {
		MenuItem menuItem = list[position];
		position = position + 1;
		return menuItem;
	}
 
	public boolean hasNext() {
		if (position >= list.length || list[position] == null) {
			return false;
		} else {
			return true;
		}
	}
  
	public void remove() {
		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;
		}
	}
}
其中我们有一个menu的接口用于创建iterator:
public interface Menu {
	public Iterator createIterator();
}
 接着我们看午餐的菜单是如何实现的:
public class DinerMenu implements Menu {
	static final int MAX_ITEMS = 6;
	int numberOfItems = 0;
	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, with a side of potato salad", false, 3.29);
		addItem("Hotdog",
			"A hot dog, with saurkraut, relish, onions, topped with cheese",
			false, 3.05);
		addItem("Steamed Veggies and Brown Rice",
			"Steamed vegetables over brown rice", true, 3.99);
		addItem("Pasta",
			"Spaghetti with Marinara Sauce, and a slice of sourdough bread",
			true, 3.89);
	}
  
	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 = numberOfItems + 1;
		}
	}
 
	public MenuItem[] getMenuItems() {
		return menuItems;
	}
  
	public Iterator createIterator() {
		return new DinerMenuIterator(menuItems);
	}
 
	// other menu methods here
}

 

最后我们来看客户,也就是我们的女招待员是如何驱使这些菜单的:

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.print(menuItem.getName() + ", ");
			System.out.print(menuItem.getPrice() + " -- ");
			System.out.println(menuItem.getDescription());
		}
	}
 
	public void printVegetarianMenu() {
		System.out.println("\nVEGETARIAN MENU\n----\nBREAKFAST");
		printVegetarianMenu(pancakeHouseMenu.createIterator());
		System.out.println("\nLUNCH");
		printVegetarianMenu(dinerMenu.createIterator());
	}
 
	public boolean isItemVegetarian(String name) {
		Iterator pancakeIterator = pancakeHouseMenu.createIterator();
		if (isVegetarian(name, pancakeIterator)) {
			return true;
		}
		Iterator dinerIterator = dinerMenu.createIterator();
		if (isVegetarian(name, dinerIterator)) {
			return true;
		}
		return false;
	}


	private void printVegetarianMenu(Iterator iterator) {
		while (iterator.hasNext()) {
			MenuItem menuItem = (MenuItem)iterator.next();
			if (menuItem.isVegetarian()) {
				System.out.print(menuItem.getName());
				System.out.println("\t\t" + menuItem.getPrice());
				System.out.println("\t" + menuItem.getDescription());
			}
		}
	}

	private boolean isVegetarian(String name, Iterator iterator) {
		while (iterator.hasNext()) {
			MenuItem menuItem = (MenuItem)iterator.next();
			if (menuItem.getName().equals(name)) {
				if (menuItem.isVegetarian()) {
					return true;
				}
			}
		}
		return false;
	}
}

 

这个就是我们客户的代码。

 

总结:

1.迭代器允许访问聚合元素,而不需要暴露它的内部结构。

2.迭代器将遍历聚合的工总封装到进另一个对象。

3.当使用迭代器的时候,我们依赖聚合提供遍历。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 《Head First设计模式-深入浅出设计模式》是一本以简单有趣的方式介绍设计模式的书籍。设计模式是在软件开发中解决特定问题的一种经验总结,它们提供了在实际开发中可重用、可靠、灵活的解决方案。 该书的主要特点是通过生动有趣的讲解和丰富多样的图表、示例来帮助读者更好地理解和应用设计模式。作者采用了大量的图形和实例来解释设计模式的概念,使读者能够迅速理解并应用这些概念。 这本书涵盖了23种常用的设计模式,如工厂模式、单例模式、适配器模式、装饰器模式等。每一种设计模式都以一个实际的例子开始,引出该模式解决的问题,然后详细解释其结构和应用,最后通过示例代码展示如何使用该模式。 此外,该书还介绍了设计模式之间的关系和如何选择合适的设计模式。它教授了读者如何在具体问题中识别出适用的设计模式,并提供了一些实际的应用建议。 《Head First设计模式-深入浅出设计模式》以其独特的教学风格和简洁明了的讲解深受读者喜爱。这本书不仅适合初学者了解设计模式,也适合有一定经验的开发人员进一步提高他们的软件设计和编程能力。 总之,这本书以其生动有趣的讲解方式和大量的图表、实例为读者介绍了设计模式的基本概念和具体应用,是学习和理解设计模式的一本不可或缺的指南。 ### 回答2: 《Head First设计模式:深入浅出设计模式》是一本主要介绍软件设计模式的书籍。设计模式是在软件开发中经常出现的问题的解决方案,可以帮助开发人员更好地构建可重用、可扩展、可维护的代码。 这本书以深入浅出的方式介绍了23种常见的设计模式,通过生动有趣的讲解和大量的图形和实例,使读者能够更加轻松地理解和掌握设计模式。它采用了非传统的学习方式,通过讲故事、练习、谜题等方式将设计模式的概念和使用方法娓娓道来。 该书首先从简单的设计模式开始,引导读者逐步理解和掌握基础的设计原则和模式,如单例模式、工厂模式等。然后,逐渐深入介绍更复杂的模式,如装饰器模式、观察者模式、策略模式等。每个模式都通过具体的案例和代码示例进行讲解,帮助读者理解模式的思想和应用场景。 除了具体的设计模式之外,这本书还关注了如何将设计模式应用到现实的软件开发中。它探讨了如何根据不同的需求选择合适的设计模式,以及如何通过设计模式提高代码的质量和可维护性。 总的来说,《Head First设计模式:深入浅出设计模式》是一本非常有趣、易懂且实用的设计模式入门书籍。无论是初学者还是有一定经验的开发人员,都能从中获得有益的知识和经验,提高软件开发的能力和效率。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值