JAVA設計模式之迭代器設計模式

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

相關文章
相關標籤/搜索