迭代器模式原理:
多个类的聚合后,提供一种方法顺序访问一个聚合对象中各个元素,不需要知道集合对象的底层实现。
从传统设计分析如下需求:
两个餐厅合并,一个用ArrayList管理菜单,一个用数组管理。传统下都将两菜单直接返回,在显示终极版本菜单时候直接将两个数据结构不同遍历方式不同地显示。这样是实现了。但内部暴露了,可以轻易修改;且如果再来一个菜单,是否又需要去修改显示终极菜单方法,不易扩展。不符合修改关闭,扩展开放的原则。
用菜单分别实现Iterator接口,终极菜单只需要获取他们的Iterator
代码入下:
/**
*统一Menu格式
*
*/
public class MenuItem {
private String name;
private int price;
public MenuItem()
{
}
public MenuItem(String name, int price) {
this.name = name;
this.price = price;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getPrice() {
return price;
}
public void setPrice(int price) {
this.price = price;
}
}
/**
*接口定义
*实现底层遍历方式
*/
public interface Iterator {
public Boolean hasNext();
public Object next();
}
/**
*A餐馆Menu
*ArraList
*其中实现Iterator并返回Iterator而不是菜单本身
*
*/
public class AMenu {
ArrayList<MenuItem> menuItems=new ArrayList<MenuItem>();
private void addItem(String name,int price)
{
MenuItem menuItem=new MenuItem(name,price);
menuItems.add(menuItem);
}
/**
* 原来返回数据结构 现在返回迭代器
* @return
*/
public Iterator getIterator(){
return new AMenuIterator();
}
class AMenuIterator implements Iterator{
/**
* 用来访问位置
*/
private int position;
AMenuIterator()
{
position=0;
}
public Boolean hasNext() {
if(position<menuItems.size())
{
return true;
}else
return false;
}
public Object next() {
MenuItem menuItem=menuItems.get(position);
position++;
return menuItem;
}
}
}
/**
*B餐馆Menu
*数组
*其中实现Iterator并返回Iterator而不是菜单本身
*
*/
public class BMenu {
MenuItem[] menuItems=new MenuItem[100];
private void addItem(String name,int price)
{
MenuItem menuItem=new MenuItem(name,price);
menuItems[menuItems.length]=menuItem;
}
/**
* 原来返回数据结构 现在返回迭代器
* @return
*/
public Iterator getIterator(){
return new BMenuIterator();
}
class BMenuIterator implements Iterator{
/**
* 用来访问位置
*/
private int position;
BMenuIterator()
{
position=0;
}
public Boolean hasNext() {
if(position<menuItems.length)
{
return true;
}else
return false;
}
public Object next() {
MenuItem menuItem=menuItems[position];
position++;
return menuItem;
}
}
}
/**
*终极菜单
*不用知道每个菜单的具体实现
*使用迭代器直接访问
*/
public class EndMenu {
private ArrayList<Iterator> iterators=new ArrayList<Iterator>();
public EndMenu()
{
}
public void addIteraor(Iterator iterator)
{
iterators.add(iterator);
}
public void printMenu(){
Iterator iterator;
MenuItem menuItem;
for(int i=0;i<iterators.size();i++)
{
iterator=iterators.get(i);
while (iterator.hasNext())
{
menuItem=(MenuItem)iterator.next();
System.out.println(menuItem.getName()+menuItem.getPrice());
}
}
}
}
/**
*main
*/
public class Main {
public static void main(String[] args) {
EndMenu endMenu=new EndMenu();
AMenu aMenu=new AMenu();
BMenu bMenu=new BMenu();
endMenu.addIteraor(aMenu.getIterator());
endMenu.addIteraor(bMenu.getIterator());
endMenu.printMenu();
}
}
/**
*省略了添加菜肴的具体代码
*/
如上,把在MenuItem之间游走的责任交给迭代器,迭代器模式就是分离了集合对象的遍历行为,抽象出一个迭代器类来负责,这样既可以做到不暴露集合的内部结构,又可让外部代码透明地访问集合内部的数据。