乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      軟件設(shè)計(jì)模式修煉 -- 迭代器模式

       行者花雕 2021-07-18

      迭代器模式是一種使用頻率非常高的設(shè)計(jì)模式,迭代器用于對一個(gè)聚合對象進(jìn)行遍歷。通過引入迭代器可以將數(shù)據(jù)的遍歷功能從聚合對象中分離出來,聚合對象只負(fù)責(zé)存儲數(shù)據(jù),聚合對象只負(fù)責(zé)存儲數(shù)據(jù),而遍歷數(shù)據(jù)由迭代器來完成。


      模式動機(jī)

      一個(gè)聚合對象,如一個(gè)列表(List)或者一個(gè)集合(Set),應(yīng)該提供一種方法來讓別人可以訪問它的元素,而又不需要暴露它的內(nèi)部結(jié)構(gòu)。此外,針對不同的需要,可能還要以不同方式遍歷整個(gè)聚合對象,但是我們不希在聚合對象的抽象層接口中充斥著各種不同遍歷的操作。怎樣遍歷一個(gè)聚合對象,又不需要了解聚合對象的內(nèi)部結(jié)構(gòu),還能提供多種不同的遍歷方式,這就是迭代器模式所要解決的問題。

      迭代器模式中,提供一個(gè)外部的迭代器來對聚合對象進(jìn)行訪問和遍歷,迭代器定義一個(gè)訪問該聚合元素的接口,并且可以跟蹤當(dāng)前遍歷對象,了解哪些元素已經(jīng)遍歷過而哪些沒有。


      模式定義

      提供一種方法來訪問聚合對象,而不用暴露這個(gè)對象的內(nèi)部表示,其別名為游標(biāo)(Cursor)。迭代器模式是一種對象行為模式。


      模式結(jié)構(gòu)

      1. Iterator(抽象迭代器)

        抽象迭代器定義了訪問和遍歷元素的接口,一般聲明以下方法:

        • 用于獲取第一個(gè)元素的 first()
        • 用于訪問下一個(gè)元素的 next()
        • 用于判斷是否還有下一個(gè)元素的 hasNext()
        • 用于獲取當(dāng)前元素的 currentItem()
      2. ConcreteIterator(具體迭代器)

        具體迭代器實(shí)現(xiàn)了抽象迭代器接口,完成對聚合對象的遍歷,同時(shí)在對聚合進(jìn)行遍歷時(shí)跟蹤其當(dāng)前位置

      3. Aggregate(抽象聚合類)

        抽象聚合類用于存儲對象,并定義創(chuàng)建相應(yīng)迭代器對象的接口,聲明一個(gè) createIterator() 方法用于創(chuàng)建一個(gè)迭代器對象

      4. ConcreteAggregate(具體聚合類)

        具體聚合類實(shí)現(xiàn)了創(chuàng)建相應(yīng)迭代器的接口,實(shí)現(xiàn)了在聚合類中聲明的 createIterator() 方法,該方法返回一個(gè)與具體聚合對應(yīng)的具體迭代器 ConcreteIterator 實(shí)例


      模式分析

      存儲數(shù)據(jù)是聚合對象的最基本職責(zé),其中包含存儲數(shù)據(jù)的類型、存儲空間的大小、存儲空間的分配,以及存儲的方式和順序。然而,聚合對象除了能存儲數(shù)據(jù)外,還必須提供遍歷訪問其內(nèi)部數(shù)據(jù)的方式,同時(shí)這些遍歷方式可能會根據(jù)不同的情形提供不同的實(shí)現(xiàn)。

      因此,聚合對象主要有兩個(gè)職責(zé):一是存儲內(nèi)部數(shù)據(jù);二是遍歷內(nèi)部數(shù)據(jù)。前者是聚合對象的基本功能,后者是可以分離的。根據(jù)單一職責(zé)原則,對象承擔(dān)的職責(zé)越少,對象的穩(wěn)定性就越好,我們將遍歷聚合對象中數(shù)據(jù)的行為提取出來,封裝到一個(gè)迭代器中,通過專門的迭代器來遍歷聚合對象的內(nèi)部數(shù)據(jù)。迭代器模式是單一職責(zé)原則的完美體現(xiàn)。

      下面通過一個(gè)簡單的自定義迭代器來分析迭代器模式的結(jié)構(gòu)

      首先定義一個(gè)簡單的迭代器去接口

      public interface MyIterator {
          void first();// 訪問第一個(gè)元素
          void next();// 訪問下一個(gè)元素
          boolean isLast();// 判斷是否是最后一個(gè)元素
          Object currentItem();// 獲取當(dāng)前元素
      }
      

      然后需要定義一個(gè)聚合接口

      public interface MyCollection {
          // 返回一個(gè) MyIterator 迭代器對象
          MyIterator createIterator();
      }
      

      定義好抽象層之后,我們需要定義抽象迭代器接口和抽象聚合接口的實(shí)現(xiàn)類,一般將具體迭代器類作為具體聚合類的內(nèi)部類,從而迭代器可以實(shí)現(xiàn)直接訪問聚合類中的數(shù)據(jù)

      public class NewCollection implements MyCollection {
          
          private Object[] obj = {"dog", "pig", "cat", "monkey", "pig"};
          
          public MyIterator createIterator() {
              return new NewIterator();
          }
          
          private class NewIterator implements MyIterator {
              
              private int currentIndex = 0;
              
              public void first() {
                  currentIndex = 0;
              }
              
              public void next() {
                  if(currentIndex < obj.length) {
                      currentIndex++;
                  }
              }
              
              public boolean isLast() {
                  return currentIndex == obj.length;
              }
              
              public void currentItem() {
                  return obj[currentIndex];
              }
          }     
      }
      

      NewCollection 類實(shí)現(xiàn)了 MyCollection 接口,實(shí)現(xiàn)了 createIterator() 方法,同時(shí)定義了一個(gè)數(shù)組用于存儲數(shù)據(jù)元素,還定義了一個(gè)實(shí)現(xiàn)了 MyIterator 接口的內(nèi)部類,索引變量 currentIndex 用于保存所操作的數(shù)組元素的下標(biāo)值??蛻舳舜a如下:

      public class Client {
          
          public static void process(MyCollection collection) {
              MyIterator i = collection.createIterator();
              while(!i.isLast()) {
                  System.out.println(i.currentItem().toString());
                  i.next();
              }
          }
          
          public static void main(String args[]) {
              MyCollection collection = new NewCollection();
              process(collection);
          }
      }
      

      除了使用內(nèi)部類實(shí)現(xiàn)之外,也可以使用常規(guī)的方式來實(shí)現(xiàn)迭代器

      public class ConcreteIterator implements Iterator {
          
          private ConcreteAggregate objects;
          
          public ConcreteIterator(ConcreteAggregate objects) {
              this.objects = objects;
          }
          
          public void first() {
              ...
          }
              
          public void next() {
              ...
          }
              
          public boolean isLast() {
              ...
          }
              
          public void currentItem() {
              ...
          }
      }
      
      public class ConcreteAggregate implements Aggregate {
          ...
          public Iterator createIterator() {
              return new ConcreteIterator(this);
          }
      }
      

      迭代器模式中應(yīng)用了工廠方法模式,聚合類充當(dāng)工廠類,而迭代器充當(dāng)產(chǎn)品類


      模式優(yōu)缺點(diǎn)

      迭代器模式優(yōu)點(diǎn):

      1. 支持以不同的方式遍歷一個(gè)聚合對象。在迭代器模式中只需要用一個(gè)不同的迭代器來替換原有迭代器即可改變遍歷算法,也可以自己定義迭代器的子類以支持新的遍歷方式。
      2. 迭代器簡化了聚合類。原有聚合對象不再需要自行提供遍歷數(shù)據(jù)等操作方法。
      3. 在同一個(gè)聚合上可以有多個(gè)遍歷。由于每個(gè)迭代器都保持自己的遍歷狀態(tài),因此可以對一個(gè)聚合對象進(jìn)行多個(gè)遍歷操作。
      4. 增加新的聚合類和迭代器類都很方便,無須修改原代碼,滿足開閉原則。

      迭代器模式缺點(diǎn):

      1. 由于迭代器模式將存儲數(shù)據(jù)和遍歷數(shù)據(jù)的職責(zé)分離,增加新的聚合類需要對應(yīng)增加新的迭代器類,類的個(gè)數(shù)成對增加,在一定程度上增加了系統(tǒng)的復(fù)雜性

      模式適用環(huán)境

      在以下情況可以使用迭代器模式:

      1. 訪問一個(gè)聚合對象的內(nèi)容而無須暴露它的內(nèi)部表示
      2. 需要為聚合對象提供多種遍歷方式
      3. 為遍歷不同的聚合結(jié)構(gòu)提供一個(gè)統(tǒng)一的接口

      Java 迭代器

      Java 中的集合框架 Collections,其基本接口層次結(jié)構(gòu)如圖

      Collection 是所有集合類的根接口,它的主要方法如下:

      boolean add(Object c);
      boolean addAll(Collection c);
      boolean remove(Object o);
      boolean removeAll(Collection c);
      boolean remainAll(Collection c);
      Iterator iterator();
      

      Collection 的 iterator() 方法返回一個(gè) java.util.Iterator 類型的對象,而其子接口 java.util.List 的 listIterator() 方法返回一個(gè) java.util.ListIterator 類型的對象,ListIterator 是 Iterator 的子類,它們構(gòu)成了 Java 語言對迭代器模式的支持。

      在 JDK 中,Iterator 接口具有如下三個(gè)基本方法:

      1. Object next():通過反復(fù)調(diào)用 next() 方法可以逐個(gè)訪問聚合中的元素
      2. boolean hasNext():用于判斷聚合對象在是否還存在下一個(gè)元素,為了不拋出異常,必須在調(diào)用 next() 之前先調(diào)用 hasNext()。如果迭代對象仍然擁有可供訪問的元素,那么 hasNext() 返回 true
      3. void remove():刪除上一次調(diào)用 next() 時(shí)返回的元素

      Java 迭代器可以理解為它工作時(shí)在聚合對象的各個(gè)元素之間,每調(diào)用一次 next() 方法,迭代器便越過下個(gè)元素,并且返回它剛越過的那個(gè)元素的地址引用。

      在第一個(gè) next() 方法被調(diào)用時(shí),迭代器由“元素1”與“元素2”之間移動至“元素2”與“元素3”之間,跨越了“元素2”,因此 next() 方法將返回對“元素2”的引用;在第二個(gè) next() 方法被調(diào)用時(shí),迭代器由“元素2”與“元素3”之間移至“元素3”與“元素4”之間,next() 方法將返回對“元素3”的引用,此時(shí)調(diào)用 remove() 方法,則可將”元素3“刪除。

      需要注意的是,next() 方法與 remove() 方法的調(diào)用是相互關(guān)聯(lián)的。如果調(diào)用 remove() 之前沒有先對 next() 進(jìn)行調(diào)用,那么將拋出異常,因?yàn)闆]有任何可供刪除的元素


        本站是提供個(gè)人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊一鍵舉報(bào)。
        轉(zhuǎn)藏 分享 獻(xiàn)花(0

        0條評論

        發(fā)表

        請遵守用戶 評論公約

        類似文章 更多