1. 程式人生 > >設計模式之三:迭代器模式

設計模式之三:迭代器模式

1. 前言

       迭代器模式(Iterator)提供了一種方法,它可以順序訪問一個物件當中的各個元素,但是又不暴露這個聚合物件的內部標示。聽起來和遍歷很像,個人感覺就是遍歷,即是,迭代器提供了一個方法,可以順序物件內部的某個容器,而不用知道容器中存放的是什麼型別.在java中,迭代器使用非常廣泛,類似於,HashSet, HashMap,ArrayList,對於它們儲存的內部元素,均可以用其內部的迭代器物件進行訪問。
    以HashSet,寫的簡單的Demo,如下:

public class myClass {
    public static void main(String[] args){
        System.out.println("This is a good test!");
        Set<String> temp = new HashSet<>();
        temp.add("11");
        temp.add("22");
        temp.add("33");
        System.out.println(" temp ="+temp);
        Iterator<String> result = temp.iterator();
        while(result.hasNext()){
            System.out.println("temp ="+result.next());
        }
    }
}

輸出:
 temp =[11, 22, 33]
 temp =11
 temp =22
 temp =33
 Process finished with exit code 0

這裡我們可以認為,迭代器是是容器內部的一個工具,通過這個工具我們可以訪問當前容器的內部元素.舉一個生活中的例子,迭代器就像一輛老式公交車上的售票員,他會向每個乘客收費.

2.框架
                

                                                                                                  迭代器UML圖

         一方面,Iterator為迭代器抽象基類,主要提供該迭代器的基本方法. ConcreteIterator 為迭代器實現類, 它內部包含了一個擁有它的物件, 通過內部方法訪問物件的容器. 另外方面, Aggregate  為實體基類,內部擁有一個抽象獲取的方法, ConcreteAggregate  為其實現內. 通過iterator  得到一個迭代器,以達到訪問內部容器的目的.

         最後, 當用戶得到一個ConcreteAggregate 的一個具體物件後,通過ConcreteAggregate.iterator() 獲得迭代器,然後就可以其內部元素了, 這也是我們最終希望達到的目的.

3.案例實現

      自己寫一個迭代器的案例:
3.1. 抽象的虛擬類

public abstract class Iterator {
    public abstract Object first();
    public abstract Object end();
    public abstract Object Next();
    public abstract Object previous();
    public abstract boolean isDone();
    public abstract boolean isDoneBackToPrevious();
    public abstract Object currentItem();
}

3.2. 抽象的實體類:

public abstract class Aggregate {
    public abstract Iterator iterator();
}

3.3.實體的迭代器類

public class ConcreteIterator extends Iterator {
    public ConcreteAggregate aggregate;
    public int current =0;
    public ConcreteIterator(ConcreteAggregate agr){
        aggregate = agr;
        current = 0/*aggregate.count()-1*/;
    }

    @Override
    public Object currentItem() {
        return aggregate.getObect(current);  }

    @Override
    public boolean isDone() {
        if (current> aggregate.count()-1) {
            return true;
        } else {
            return false;
        }
    }

    @Override
    public boolean isDoneBackToPrevious(){
        if (current > 0) {
            return true;
        }
        return false;
    }

    @Override
    public Object next() {
        Object temp = null;
        current++;
        if (current < aggregate.count()) {
            temp = aggregate.getObect(current);
        }
        return temp;
    }

    @Override
    public Object previous() {
        Object temp = null;
        current--;
        if (current >-1){
            temp = aggregate.getObect(current);
        }
        return temp;
    }

    @Override
    public Object end() {
        return aggregate.getObect(aggregate.count()-1);
    }

    @Override
    public Object first() {
        return aggregate.getObect(0);
    }
}

3.4. 實體的物件類

這個類需要使用迭代器類

public class ConcreteAggregate extends Aggregate {
    private List temp = new ArrayList();

    @Override
    public Iterator iterator() {
        return new ConcreteIterator(this);
    }
    public int count(){
        if (temp == null) {
            return 0;
        } else {
            return temp.size();
        }
    }
    public Object getObect(int index){
        return  temp.get(index);
    }
    public void setObject(int index , Object value){
        temp.add(index, value);
    }
}

3.5. 主函式

主要的主要功能是new 物件類,然後使用其了內部的迭代器類進行實驗. 這裡使用倒序訪問內部元素進行測試(刪除部分程式碼,把註釋的程式碼還原,就可以進行從正序訪問)

public class myClass {
    public static void main(String[] args){
        ConcreteAggregate temp = new ConcreteAggregate();
        temp.setObject(0, "One");
        temp.setObject(1,"Two");
        temp.setObject(2, "Three");
        Iterator iterator = temp.iterator();
        if (iterator != null){
            while (!iterator.IsDone()){
                System.out.println("-------"+iterator.CurrentItem());
                iterator.Next();
            }
        }
    }
}

輸出:

-------One
-------Two
-------Three

Process finished with exit code 0