设计模式之迭代器模式以及单一职责原则
我们在使用集合的时候,往往需要用到遍历,这时候需要使用迭代器,但是不同集合的遍历方法不一样,所以迭代器的实现方法也不一样,但是为了面向抽象编程,客户端应该只知道如何使用迭代器进行遍历,而不需要知道迭代器是怎么实现的。这里就用到了迭代器模式。
所以说迭代器模式,就是对于不同集合,使用相同的迭代器接口,但采用不同的实现,也就是封装遍历。
比如说,客户端要实现对集合的遍历,这时候如果面向实现编程,就要知道有多少个集合,要怎么样遍历集合。但是如果采用了迭代器,客户端则只需要知道迭代器有哪些方法,是怎么使用的即可。
比如这时候我们需要遍历一个数组和一个ArrayList,ArrayList本来就是实现了Iterator接口,所以我们使用现成的,但是数组则不是,所以我们要自己编写一个类,实现Iterator接口,类图如下:
ArrayIterator类
import java.util.Iterator;
/**
用来对数组进行迭代的迭代器
**/
public class ArrayIterator implements Iterator
{
MenuItem[] items;
int position;
public ArrayIterator(MenuItem[] items)
{
this.items=items;
position=0;
}
public boolean hasNext()
{
if(items!=null)
{
if(position<items.length-1)
{
return true;
}
else
return false;
}
return false;
}
public Object next()
{
return items[position++];
}
public void remove()
{
throw new UnsupportedOperationException();
}
}
DinerMenu类
/**
使用数组来保存
**/
import java.util.Iterator;
public class DinerMenu implements Menu
{
MenuItem[] items;
public DinerMenu()
{
items=new MenuItem[3];
MenuItem temp;
temp=new MenuItem("noodles",20);
items[0]=temp;
temp=new MenuItem("rice",30);
items[1]=temp;
temp=new MenuItem("cup cake",5);
items[2]=temp;
}
public MenuItem[] getMenuItems()
{
return items;
}
public Iterator createIterator()
{
return new ArrayIterator(items);
}
}
另一个集合:PancakeHouseMenu类
import java.util.ArrayList;
import java.util.Iterator;
/**
使用ArrayList来保存
**/
public class PancakeHouseMenu implements Menu
{
ArrayList items;
public PancakeHouseMenu()
{
items=new ArrayList();
items.add(new MenuItem("cake",10));
items.add(new MenuItem("pizza",10));
items.add(new MenuItem("pancake",20));
}
public ArrayList getMenuItems()
{
return items;
}
public Iterator createIterator()
{
return items.iterator();
}
}
Client类
import java.util.Iterator;
import java.util.HashMap;
/**
Client
**/
public class Waitress
{
HashMap<String,Menu> menus;
public Waitress()
{
menus=new HashMap<String,Menu>();
}
public void addMenu(String name,Menu menu)
{
menus.put(name,menu);
}
public void printMenu()
{
for(String key:menus.keySet())
{
Menu menu=menus.get(key);
System.out.println(key);
Iterator iterator=menu.createIterator();
while(iterator.hasNext())
{
MenuItem menuItem=(MenuItem)iterator.next();
System.out.println(menuItem);
}
}
}
}
Waitress类不需要知道它存储的集合是什么,只需要运用Iterator接口以及Menu接口就可以遍历所有集合了,这时候如果要添加新的集合也只需要再写两个类,一个实现Menu接口,一个实现Iterator接口即可。Menu接口有点类似于抽象工厂,负责实例化Iterator对象。
由此我们引出了一个设计原则——“单一职责原则”,意思是,一个类应该只有一个引起它变化的原因,一个类应该只有一个职责。像上面的例子,DinerMenu只需要管理好MenuItem即可,对它的遍历是由ArrayIterator来帮它实现,如果对于遍历有需要修改的,也只需要修改ArrayIterator就可以了。
浙公网安备 33010602011771号