回归

蓦然回首,那人却在灯火阑珊处

  BlogJava :: 首页 :: 联系 :: 聚合  :: 管理
  4 Posts :: 2 Stories :: 12 Comments :: 0 Trackbacks

2007年7月27日 #

 

         前些時工作忙,中間停頓一段時間,今天繼續。向關注這里的文章的博友們表示抱歉。
         今天說說一個簡單的模式,迭代器模式(Iterator),他屬于行為模式中的一種。

         [形成]

         在Java程序中,在輸出List類型的對象時候,出現最多的程式塊就是:
         

1     for (int i = 0 ;i<list.size; i++){
2         XXX x = (XXX)list.get(i);
3     }

 

其中list 是List 類型,里邊放著若干個XXX類型的對象。
這種 方式是采用i++遞增的方式來遍歷list中的所有對象來進行相關操作。對于設計模式,把i的功能抽象劃的結果就是:Iterator Pattern

Iterate 中文的意思是“迭代,反復”,Iterator 的意思可以理解為“迭代器”。

       [代码示例]
        示例程式是把書(Book)放到書架上(BookShelf)上,并依次輸出書名。
         
         程式列表
   
名稱 說明
Aggregate 表示已聚合的接口
Iterator 執行遞增,遍歷的接口
Book 表示書籍的類
BookShelf 表示書架的類
BookShelfIterator 掃描書架的類
Main 測試用的類

   
          










[UML图]






      [示例代码和类的诠释]

1 package Iterator;
2 
3 import java.util.Iterator;
4 
5 public interface Aggregate {
6     public abstract Iterator iterator();
7 }
8 

Aggregate 接口:
     該接口只聲明了一個方法,建立一個可以對應聚合的Iterator.,當需要遍歷某個聚合對象時,調用Iterator方法可以建立一個實現Iterator接口的類的對象實例。

1 package Iterator;
2 
3 public interface Iterator {
4     public abstract boolean hasNext();
5     public abstract Object next();
6 }
7 

Iterator 接口:
這是該模式的核心接口,Iterator接口執行元素的遞增,具有循環遍歷的功能。Iterator的接口的方法因需要而定,我們可以初步確定接口方法:
hasNext() :是檢查有沒有“下一個元素”,返回boolean.(有,返回true,,無,返回false)
next();取得“下一個元素”,同時把取對象的指針指向下一個元素,以便下次調用next方法的時候確實能取到下一個元素。這些具體實現還得看具體的實現Iterator接口的類的實現才知道

 1 package Iterator;
 2 
 3 public class Book {
 4     private String name = "";
 5 
 6     public Book(String name) {
 7         this.name = name;
 8     }
 9 
10     public String getName() {
11         return name;
12     }
13 }
14 

Book 類:
表示書籍的類,比較簡單,通過getName方法得到書的名字,書名是以構造函數初始化對象的時候用參數來字號定。


 1 package Iterator;
 2 
 3 public class BookShelf implements Aggregate{
 4     private Book[] books;
 5     private int last = 0;
 6     
 7     public BookShelf(int maxsize){
 8         this.books = new Book[maxsize];
 9     }
10         
11     public Book getBookAt(int index){
12         return books[index];
13     }
14     public void appendBook(Book book){
15         this.books[last] = book;
16         last++;
17     }
18     
19     public int getLength(){
20         return last;
21     }
22     public Iterator iterator(){
23         return new BookShelfIterator(this);
24     }
25 }
26 


BookShelfl類:
     該類是表現書架作用的類,保證實現Aggregate接口所聲明的Iterator方法里返回實現Iterator接口的實例。如果需要遍歷書架上的書,調用iterator方法。books數組存放的對象就是book,書架大小可以在一開始建立時設置大小,當然我們可以不用數組而采用java.util.Vector,就可以往書架上放超過指定數量的書籍。


 1 package Iterator;
 2 
 3 public class BookShelfIterator implements Iterator{
 4     private BookShelf bookShelf;
 5     private int index;
 6     public BookShelfIterator(BookShelf bookShelf){
 7         this.bookShelf = bookShelf;
 8         this.index =0;
 9     }
10     
11     public boolean hasNext(){
12         if(index < bookShelf.getLength()){
13             return true;
14         }else{
15             return false;
16         }
17     }
18     
19     public Object next(){
20         Book book = bookShelf.getBookAt(index);
21         index++;
22         return book;
23     }
24 
25 }
26 

BookShelfIterator類:

      字段bookShelf指定BookShelfIterator所要掃描的書架,而index字段則是指向目前該書的下標。
      構造函數把傳過來的BookShelf對象實例儲存在bookShelf字段,將index設置為0.
      實現的hasNext方法判斷是否有下一本書的標準是根據index是否小于書架上書籍的數量(表達式bookShelf.getLength()的值)來判斷。
      next方法返回目前該書,并進入到“下一個”。兩步:第一步先把取得當面的書籍保留在book變量,然后把循環變量推到“下一個”。


 1 package Iterator;
 2 
 3 public class Main {
 4     /**
 5      * @param args
 6      */
 7     public static void main(String[] args) {
 8         BookShelf bookShelf = new BookShelf(3);
 9         bookShelf.appendBook(new Book("book1"));
10         bookShelf.appendBook(new Book("book2"));
11         bookShelf.appendBook(new Book("book3"));
12         Iterator it  = bookShelf.iterator();
13         while(it.hasNext()){
14             Book book = (Book)it.next();
15             System.out.println(" "+book.getName());
16         }
17     }
18 
19 }
20 

Main類:
     1.先放三本書上架
      2.通過調用書架的iterator方法得到迭代器,來進行循環遍歷
      3.循環遍歷書籍,取出書,打印出書的名字。


示例程序的执行结果 book1
 book2
 book3

回顧一下,在迭代器模式中幾個重要“角色”:
     迭代器: 定義了訪問和遍歷元素的接口 ,它定義了能否取得下一個元素信息的的hasNext方法和取得下一個元素的next方法
    具體的迭代器:實現了迭代器的接口,如本例的BookShelfIterator,掌握遍歷時的重要信息。
    聚合:定義了建立了Iterator的接口。如本例的:Aggregate接口,定義了Iterator方法
   具體聚合:實現了聚合的所定義的接口,如本例的BookShelf,它實現了Iterator方法。


      [拓展思考]
       有人回想,干嘛搞這么麻煩,用一個for不就是可以遍歷數組或List碼?思考一下迭代器的結構。Iterator是把定義和實現分開

        while(it.hasNext()){
                           Book book = (Book)it.next();
                        System.out.println(" "+book.getName());
          }
      這里我只調用了Iterator接口的hasNext和next方法,并沒有調用BookShelf實現遍歷是需要的方法,如:getBookAt()。這里的while不會收到BookShelf的實現影響。
      假設這里我們不采用數組來管理BookShelf,而采取與Java.util.Vector來管理。無論BookShelf的如何修改,都Main測試程序里無需修改任何程序就可以運行,這就是設計模式的優勢。設計模式是為了提高類的服用率,如果把一個零件修改了,就不想要修改其他使用了改零件的部分。

 
posted @ 2007-07-27 15:22 回归 阅读(1177) | 评论 (2)编辑 收藏