1、迭代器模式簡介java
Iterator模式也叫迭代模式,是行爲模式之一,它把對容器中包含的內部對象的訪問委讓給外部類,使用Iterator(遍歷)按順序進行遍歷訪問的設計模式。設計模式
2、迭代器模式的角色與職責數組
Iterator(迭代器接口):該接口必須定義實現迭代功能的最小定義方法集好比提供hasNext()和next()方法。ide
ConcreteIterator(迭代器實現類):迭代器接口Iterator的實現類。能夠根據具體狀況加以實現。測試
Aggregate(容器接口):定義基本功能以及提供相似Iterator iterator()的方法。this
concreteAggregate(容器實現類):容器接口的實現類。必須實現Iterator iterator()方法。url
3、迭代器模式的具體實現spa
有一個餐廳和煎餅屋要合併,可是每一個老闆都只想用本身的菜單模式,餐廳使用的是數組形式的菜單,而煎餅屋使用的是ArrayList形式。.net
雖然實現形式不太同樣,可是每一個菜單項的內容是同樣的,咱們看一下菜單項的設計,比較常規的列出了名稱、描述、是不是素食、價格:設計
// An highlighted block
package design.iterator.gys.noiterator;
public class MenuItem {
String name;
String desc;
boolean vegetarian;
double price;
public MenuItem(String name, String desc, boolean vegetarian, double price) {
super();
this.name = name;
this.desc = desc;
this.vegetarian = vegetarian;
this.price = price;
}
public String getName() {
return name;
}
public String getDesc() {
return desc;
}
public boolean isVegetarian() {
return vegetarian;
}
public double getPrice() {
return price;
}
}
1、不使用迭代器模式
一開始老闆們互不相讓,不肯意更改本身的菜單,那咱們就瞧一眼兩個菜單吧。
餐廳:
// An highlighted block
package design.iterator.gys.noiterator;
public class DinnerMenu {
static final int Max=6;
int numberOfItem=0;
MenuItem[] menu;
public DinnerMenu() {
menu=new MenuItem[Max];
addItem("a2","b2",true,6.99);
addItem("c2","d2",false,7.99);
addItem("e2","f2",true,8.99);
addItem("g2","h2",false,9.99);
}
public void addItem(String name,String desc,boolean vegetarian,double price){
MenuItem mt=new MenuItem(name, desc, vegetarian, price);
if(numberOfItem>=Max)
System.out.println("menu is full");
else
{
menu[numberOfItem]=mt;
numberOfItem++;
}
}
public MenuItem[] getMenu() {
return menu;
}
}
煎餅屋:
// An highlighted block
package design.iterator.gys.noiterator;
import java.util.ArrayList;
public class PancakeHouseMenu {
ArrayList menu;
public PancakeHouseMenu() {
menu=new ArrayList();
addItem("a1","b1",true,1.99);
addItem("c1","d1",false,2.99);
addItem("e1","f1",true,3.99);
addItem("g1","h1",false,4.99);
}
public void addItem(String name,String desc,boolean vegetarian,double price){
MenuItem mt=new MenuItem(name, desc, vegetarian, price);
menu.add(mt);
}
public ArrayList getMenu() {
return menu;
}
}
果真風格迥異啊,這下可忙壞了服務員,得區分開兩個菜單,否則一不當心可就要出洋相了。首先要取得菜單的形式,還都不同,服務員須要對二者分別進行迭代:
// An highlighted block
package design.iterator.gys.noiterator;
import java.util.ArrayList;
public class Waitress {
private PancakeHouseMenu menu1;
private DinnerMenu menu2;
public Waitress(PancakeHouseMenu menu1, DinnerMenu menu2) {
super();
this.menu1 = menu1;
this.menu2 = menu2;
}
public void printMenu()
{
ArrayList breakfastMenu=menu1.getMenu();
MenuItem[] lunchMenu=menu2.getMenu();
System.out.println("***PancakeHouseMenu***");
for(int i=0;i<breakfastMenu.size();i++)
{
MenuItem mt=(MenuItem)breakfastMenu.get(i);
System.out.println(mt.getName()+" "+mt.getDesc()+" "+mt.getPrice());
}
System.out.println("***DinnerMenu***");
for(int i=0;i<lunchMenu.length && lunchMenu[i]!=null;i++)
{
MenuItem mt=lunchMenu[i];
System.out.println(mt.getName()+" "+mt.getDesc()+" "+mt.getPrice());
}
}
}
看看餐廳的運行狀況:
// An highlighted block
package design.iterator.gys.noiterator;
public class Test {
public static void main(String[] args) {
// TODO Auto-generated method stub
PancakeHouseMenu m=new PancakeHouseMenu();
DinnerMenu d=new DinnerMenu();
Waitress w=new Waitress(m, d);
w.printMenu();
}
}
// An highlighted block
***PancakeHouseMenu***
a1 b1 1.99
c1 d1 2.99
e1 f1 3.99
g1 h1 4.99
***DinnerMenu***
a2 b2 6.99
c2 d2 7.99
e2 f2 8.99
g2 h2 9.99
很好,沒出什麼大的問題,服務員可算是盡心盡職的了。
那麼問題來了,服務員須要兩個循環來遍歷外匯返傭菜單項,而且服務員和具體的菜單捆綁在一塊兒,沒法進行更多的功能擴展,而且兩個菜單的內部實現徹底暴露給了服務員,雖然咱們不肯以爲他是壞人,可是萬一呢。
2、使用迭代器模式
方案設計
類設計
爲了減輕服務員的工做,讓她只熟悉一個接口就能將全部的菜單打印出來。
首先咱們對迭代器類進行抽象,可是仍然將菜單的內容留給廚師進行更改,而且在這裏咱們使用的是自定義的迭代器形式。
// An highlighted block
package design.iterator.gys.iterator;
public interface Iterator {
public boolean hasNext();
public Object next();
}
下面是餐廳迭代器的實現,因爲菜單是數組類型,咱們使用數組下標進行設計,因爲是固定長度的數組,咱們不只要判斷索引是否超過也要判斷數組的內容是否爲空:
// An highlighted block
package design.iterator.gys.iterator;
import design.iterator.gys.noiterator.MenuItem;
public class DinnerMenuIterator implements Iterator{
private MenuItem[] menu;
private int start=0;
public DinnerMenuIterator(MenuItem[] menu) {
super();
this.menu = menu;
}
@Override
public boolean hasNext() {
// TODO Auto-generated method stub
if(start<menu.length&&menu[start]!=null)
return true;
else
return false;
}
@Override
public Object next() {
// TODO Auto-generated method stub
return menu[start++];
}
}
煎餅屋的菜單使用ArrlyList實現的,屬於可變長度:
// An highlighted block
package design.iterator.gys.iterator;
import java.util.ArrayList;
public class PancakeHouseMenuIterator implements Iterator{
private ArrayList menu;
private int start=0;
public PancakeHouseMenuIterator(ArrayList menu) {
super();
this.menu = menu;
}
@Override
public boolean hasNext() {
// TODO Auto-generated method stub
if(start<menu.size())
return true;
else
return false;
}
@Override
public Object next() {
// TODO Auto-generated method stub
return menu.get(start++);
}
}
至此,咱們實現了兩個菜單的迭代器。那麼接下來咱們就要在菜單內部進行處理,以便讓服務員得到這個迭代器。
餐廳:
// An highlighted block
package design.iterator.gys.iterator;
import design.iterator.gys.noiterator.MenuItem;
public class DinnerMenu {
static final int Max=6;
int numberOfItem=0;
MenuItem[] menu;
public DinnerMenu() {
menu=new MenuItem[Max];
addItem("a2","b2",true,6.99);
addItem("c2","d2",false,7.99);
addItem("e2","f2",true,8.99);
addItem("g2","h2",false,9.99);
}
public void addItem(String name,String desc,boolean vegetarian,double price){
MenuItem mt=new MenuItem(name, desc, vegetarian, price);
if(numberOfItem>=Max)
System.out.println("menu is full");
else
{
menu[numberOfItem]=mt;
numberOfItem++;
}
}
public Iterator createIterator() {
return new DinnerMenuIterator(menu);
}
}
煎餅屋:
// An highlighted block
package design.iterator.gys.iterator;
import java.util.ArrayList;
import design.iterator.gys.noiterator.MenuItem;
public class PancakeHouseMenu {
ArrayList menu;
public PancakeHouseMenu() {
menu=new ArrayList();
addItem("a1","b1",true,1.99);
addItem("c1","d1",false,2.99);
addItem("e1","f1",true,3.99);
addItem("g1","h1",false,4.99);
}
public void addItem(String name,String desc,boolean vegetarian,double price){
MenuItem mt=new MenuItem(name, desc, vegetarian, price);
menu.add(mt);
}
public Iterator createIterator() {
return new PancakeHouseMenuIterator(menu);
}
}
看看新來的服務員適應如何:
// An highlighted block
package design.iterator.gys.iterator;
import design.iterator.gys.noiterator.MenuItem;
public class Waitress {
PancakeHouseMenu menu1;
DinnerMenu memu2;
public Waitress(PancakeHouseMenu menu1, DinnerMenu memu2) {
super();
this.menu1 = menu1;
this.memu2 = memu2;
}
public void printMenu() {
Iterator i1=menu1.createIterator();
printMenu(i1);
System.out.println("----------");
Iterator i2=memu2.createIterator();
printMenu(i2);
}
public void printMenu(Iterator iterator)
{
while(iterator.hasNext()) {
MenuItem m=(MenuItem)iterator.next();
System.out.println(m.getName()+" "+m.getDesc()+" "+m.getPrice());
}
}
}
So easy!如今服務員只須要調用每一個菜單的迭代器,就能實現對菜單的遍歷,不用再去了解內部的實現機制了。
// An highlighted block
package design.iterator.gys.iterator;
public class Tset {
public static void main(String[] args) {
// TODO Auto-generated method stub
PancakeHouseMenu p=new PancakeHouseMenu();
DinnerMenu d=new DinnerMenu();
Waitress w=new Waitress(p, d);
w.printMenu();
System.out.println("**********");
Iterator i=d.createIterator();
w.printMenu(i);
}
}
測試結果:
// An highlighted block
a1 b1 1.99
c1 d1 2.99
e1 f1 3.99
g1 h1 4.99
----------
a2 b2 6.99
c2 d2 7.99
e2 f2 8.99
g2 h2 9.99
**********
a2 b2 6.99
c2 d2 7.99
e2 f2 8.99
g2 h2 9.99
效果不錯,而且能單獨對一個菜單進行輸出了。
————————————————
原文連接:https://blog.csdn.net/qq_22118991/article/details/84968047