在一个类中 “遍历集合内对象的过程”可以用迭代器进行封装。迭代器模式依赖于一个迭代器接口,在子类中给出相应的具体遍历对象的方法实现,并把这个迭代器挂钩到类中。
迭代器接口
public interface Interator{
boolean hasnext();
Object next();
}
实现一个具体的迭代器
public class DinerMenuInterator implements Interator{
MenuItem[] items;
int position=0; //记录数组集合的位置
public DinreMenuInterator(Menultem[] items){ //传入一个集合
this.items=items;
}
//给出相应的方法实现
public boolean hasnext(){
if(items.length<=position||items[position]==null)
return false;
else
return turn;
}
public Object next(){
MenuItem menuItem=items[position];
position=position+1;
return menultem;
}
}
挂钩到原来遍历集合的类中
public class DinerMenu{
stastic final int MAX_ITEMS=6;
int numberOFItems=0;
MenuItem[] menuItems;
//构造器,用来初始化数组,添加方法的调用
public DinerMenu(){
menulItems=new MenuItem[MAX_ITEMS];
addItem("","");
}
public void addItem(..){
}
//返回迭代器接口给客户
public Iterator createIterator(){
return new DinerMenuInterator(nebuItems);
}
//其他方法
}
客户
public class Waitress{
DinerMenu dinerMenu;
//
//构造器引入DinerMenu类
public Waitress{
this.dinerMenu=dinerMenu;
//
}
//调用该类返回接口
public void printMenu(){
Iterator dinerIterator=dinerMenu.createIterator();
printMenu(dinerIterator);
//引入其他类的迭代器
}
//对于所有的迭代器只需要这一个方法
private void printMenu(Iterator iterator){ //参数,多态
while(iterator.hasnext(){
MenuItem menuItem=(MenuItem)iterator.next();
//
}
}
}
客户通过迭代器遍历从具体类的实现中解耦,不再依赖集合。
java.util内置了Iterator接口(Arraylist也有一个返回迭代器的iterator(),Collection、Framework的ListIteartor接口,Enumeration)
这个接口中还有一个remove方法,可以从删除集合中返回的最后一项
使用ArrayList的接口,修改返回的实现
public Iterator createIterator(){
return menuItems.iterator();
}
使用util的内置接口,在迭代器中再给出remove()等方法实现
不同的迭代器中createIterator()等方法是不尽相同的,我们可以把方法抽象到接口中来,面向抽象编程
public interface Menu{
public Iterator createIterator();
}
相应的实现这个方法的DinerMenu等类要实现接口,客户中直接使用Menu接口引用实现进
一步解耦。另外我们可以随时根据需要扩展这个接口。
以上,最终客户只需要关注Menu和迭代器两个接口。
迭代器模式:提供一种方法顺序访问一个集合对象中的各个元素,而又不暴露其内部的表示。
单一责任原则:一个类应该只有一个引起变化的原因(避免类的改变)
内聚:度量一个类或模块紧密的达到某个单一目的或责任。
简化上面的代码:把多个返回构造器的类打包进ArrayList,然后遍历取得他们的迭代器,再进行遍历。
当结构再复杂时,可以使用组合模式来解决。
组合模式:允许你将对象组合成树形结构来表现“整体/部分”层次结构。组合能让客户以一致的方式(相同操作)处理个别对象以及对象组合。
创建一个组件接口作为个别对象、对象组合的共同接口(使用抽象类提供默认实现)
客户使用组件接口访问个别对象以及对象组合
个别对象以及对象组合覆盖一些对它有意义的方法
对象组合中引入ArrayList记录它的孩子们,个别对象以及对象组合同一方法的不同实现因为接口相同可以统一遍历调用
对于特定次序的孩子可能需要更复杂的方案
组合模式以单一责任原则换取透明性(责任分开客户就需要instanceof操作)
客户要遍历整个组合就要实现一个组合迭代器
抽象类中加上createIterator()方法,对象组合的实现中需要返回空迭代器
组合迭代器是一个层次遍历的过程,实现Iterator接口,采用Stack维护组合递归结构(外部迭代器)
一些细节。。比如在打印操作时对对象的选择方法(instanceof,改写isVegetarian())
通过缓存减少遍历代价
组合模式提供了一种结构同时包容个别对象和对象组合,在平衡透明性和安全性之间有许多折衷方案。