設計模式(十一):迭代器模式

来源:http://www.cnblogs.com/jenkinschan/archive/2016/11/15/5771584.html
-Advertisement-
Play Games

一、概述 迭代器模式提供一種方法順序訪問一個聚合對象中的各個元素,而又不暴露其內部的表示。 二、解決問題 迭代器模式就是提供一種遍歷元素的統一介面,用一致的方法遍歷聚合元素。試想,如果我們的聚合元素是用不同的方式實現的,有些用了數組,有些用了java的集合類,或者還有其他方式,當客戶端要遍歷這些元素 ...


一、概述

  迭代器模式提供一種方法順序訪問一個聚合對象中的各個元素,而又不暴露其內部的表示。

二、解決問題

  迭代器模式就是提供一種遍歷元素的統一介面,用一致的方法遍歷聚合元素。試想,如果我們的聚合元素是用不同的方式實現的,有些用了數組,有些用了java的集合類,或者還有其他方式,當客戶端要遍歷這些元素的時候就要使用多種遍歷方式,而且還會暴露元素的內部結構。

三、應用實例

  下麵我用一個在頁面展示一個學校院繫結構的例子來講解迭代器的用法,講完例子後我們再來看看迭代器的結構類圖。現在我們的需求是這樣,要在一個頁面中展示出學校的院系組成,它應該是樹狀結構的,一個學校有多個學院,一個學院有多個系。當然了,頁面的具體代碼就不寫了,我們就來分析後臺的實現方法。

  前面學了面向介面編程,我們現在可以把學院抽象出來做成一個介面,設定裡面方法有getName,addDepartment(增加一個系),一個可以遍歷全部系的方法(暫且取名為CreateIterator,就是返回一個迭代器的方法)。看看介面的代碼實現

package com.jet.someinterface;

import java.util.Iterator;

/**
 * Created by Administrator on 2016/11/14.
 */
public interface College {

    public String getName();

    /**
     * 增加一個系的方法
     */
    public void addDepartment(String name,String description);

    /**
     *返回一個迭代器用來遍歷每一個系
     */
    public Iterator createIterator();

} 

  學院下麵的是專業,我們把專業的對象創建出來

package com.jet.com.jet.vo;

/**
 * Created by Administrator on 2016/11/14.
 * description:專業對象
 */
public class DepartmentVo {
    private String name;
    private String description;

    public DepartmentVo(String name, String description) {
        this.name = name;
        this.description = description;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public String getName() {

        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

  創建第一學院對象(電腦學院),及其對應的迭代器

package com.jet.impl;

import com.jet.com.jet.vo.DepartmentVo;
import com.jet.someinterface.College;

import java.util.Iterator;

/**
 * Created by Administrator on 2016/11/14.
 * description:電腦學院
 */
public class ComputerCollege implements College{
    DepartmentVo[] departmentVos;//用來放置專業對象,註意這裡用的是數組
    int numberOfDepartments = 0;//保存當前數組已有對象數
    static final int MAX_DEPARTMENTS = 4;//控制專業數組大小

    public String getName() {
        return "電腦學院";
    }

    public ComputerCollege() {
        departmentVos = new DepartmentVo[MAX_DEPARTMENTS];
        addDepartment("電腦科學與技術","電腦科學與技術");
        addDepartment("軟體工程 ","軟體工程 ");
        addDepartment("網路工程","網路工程");
        addDepartment("信息安全","信息安全");
    }

    public void addDepartment(String name,String description) {
        if(numberOfDepartments >= MAX_DEPARTMENTS){
            System.out.println("已超過學院最專業數限制,不能添加專業了!");
        }else{
            DepartmentVo departmentVo = new DepartmentVo(name,description);
            departmentVos[numberOfDepartments] = departmentVo;
            numberOfDepartments = numberOfDepartments + 1;
        }
    }

    public Iterator createIterator() {
        //返回一個遍歷器
        return new ComputerCollegeIterator(departmentVos);
    }
}
package com.jet.impl;

import com.jet.com.jet.vo.DepartmentVo;

import java.util.Iterator;

/**
 * Created by Administrator on 2016/11/14.
 * decription:電腦學院的遍歷器,我們這裡是實現了java自帶的便利器Iterator
 */
public class ComputerCollegeIterator implements Iterator{
    DepartmentVo[] departmentVos;
    int position = 0;//遍歷的位置

    public ComputerCollegeIterator(DepartmentVo[] departmentVos) {
        this.departmentVos = departmentVos;
    }

    public boolean hasNext() {
        if(position >= departmentVos.length || departmentVos[position] == null ){
            return false;
        }else{
            return true;
        }
    }

    public Object next() {
        DepartmentVo departmentVo = departmentVos[position];
        position = position + 1;
        return departmentVo;
    }

    //刪除的方法我們暫時不實現
    public void remove() {
    }
}

   創建第二個學院(信息工程學院)及其迭代器

package com.jet.impl;

import com.jet.com.jet.vo.DepartmentVo;
import com.jet.someinterface.College;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

/**
 * Created by Administrator on 2016/11/14.
 * description:信息工程學院
 */
public class InfoEngineeringCollege implements College{
    List<DepartmentVo> departmentVoList;//註意這裡我們使用了集合來放置專業對象了

    public String getName() {
        return "信息工程學院";
    }

    public InfoEngineeringCollege() {
        this.departmentVoList = new ArrayList<DepartmentVo>();
        addDepartment("電子信息工程","電子信息工程");
        addDepartment("信息工程","信息工程");
        addDepartment("通信工程","通信工程");
    }

    public void addDepartment(String name, String description) {
        DepartmentVo departmentVo = new DepartmentVo(name,description);
        departmentVoList.add(departmentVo);
    }

    public Iterator createIterator() {
        return new InfoEngineeringCollengIterator(departmentVoList);
    }
}

 

package com.jet.impl;

import com.jet.com.jet.vo.DepartmentVo;
import java.util.Iterator;
import java.util.List;

/**
 * Created by Administrator on 2016/11/14.
 * description:信息工程學院迭代器
 */
public class InfoEngineeringCollengIterator  implements Iterator{
    int index = 0;
    List<DepartmentVo> departmentVoList;

    public InfoEngineeringCollengIterator(List<DepartmentVo> departmentVoList) {
        this.departmentVoList = departmentVoList;
    }

    public boolean hasNext() {
        if(index >= departmentVoList.size() ){
            return false;
        }else {
            index = index + 1;
            return true;
        }

    }

    public Object next() {
        return departmentVoList.get(index);
    }

    public void remove() {

    }
} 

  創建數據輸出類(也就是客戶端)

package com.jet.impl;

import com.jet.com.jet.vo.DepartmentVo;
import com.jet.someinterface.College;
import java.util.Iterator;
import java.util.List;

/**
 * Created by Administrator on 2016/11/15.
 * description:模擬向頁面輸出院系信息的類,該類負責遍歷每個專業並列印其信息
 */
public class OutputInfoImpl {
    //學院集合
    List<College> collegeList;

    public OutputInfoImpl(List<College> collegeList) {
        this.collegeList = collegeList;
    }

    public void printDepartement(){
        //java的集合實現了迭代器,可以直接調用方法取到
        Iterator departmentIterator = collegeList.iterator();
        while (departmentIterator.hasNext()){
            College college = (College) departmentIterator.next();
            System.out.println("--------" + college.getName() + "有以下專業-----------");
            printDepartment(college.createIterator());
        }
    }

    public void printDepartment(Iterator iterator){
        while (iterator.hasNext()){
            DepartmentVo departmentVo = (DepartmentVo) iterator.next();
            System.out.println(departmentVo.getName());
        }
    }

}

  測試迭代器

package com.jet.test;

import com.jet.impl.ComputerCollege;
import com.jet.impl.InfoEngineeringCollege;
import com.jet.impl.OutputInfoImpl;
import com.jet.someinterface.College;

import java.util.ArrayList;
import java.util.List;

/**
 * Created by Administrator on 2016/11/15.
 * description:測試迭代器
 */
public class IteratorTest {
    public static void main(String[] args) {
        //創建學院集合
        List<College> collegeList = new ArrayList<College>();
        College computerCollege = new ComputerCollege();
        College infoEngineeringCollege = new InfoEngineeringCollege();
        collegeList.add(computerCollege);
        collegeList.add(infoEngineeringCollege);

        OutputInfoImpl outputInfo = new OutputInfoImpl(collegeList);
        outputInfo.printDepartement();
    }
}

測試結果:

四、結構類圖

五、使用場景

  當要展示一組相似對象,或者遍歷一組相同對象時使用。

六、優缺點

  1、優點

  (1)、提供一個統一的方法遍歷對象,客戶不用再考慮聚合的類型,使用一種方法就可以遍歷對象了。

  (2)、隱藏了聚合的內部結構,客戶端要遍歷聚合的時候只能取到迭代器,而不會知道聚合的具體組成。

  (3)、提供了一種設計思想,就是一個類應該只有一個引起變化的原因(叫做單一責任原則)。在聚合類中,我們把迭代器分開,就是要把管理對象集合和遍歷對象集合的責任分開,這樣一來集合改變的話,隻影響到聚合對象。而如果遍歷方式改變的話,隻影響到了迭代器。

  2、缺點

    每個聚合對象都要一個迭代器,會生成多個迭代器不好管理類。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 方法屬於誰 方法要麼屬於類,要麼屬於對象 static修飾的方法屬於類 沒有static修飾的方法屬於對象 方法只能定義在類裡面,不能獨立定義 不能獨立的執行方法,要麼通過類調用,要麼通過方法調用 一個類里,一個方法調用另一個方法,看似沒有調用者,實際上對於非static方法使用this調用,sta ...
  • 一、spring aop execution表達式說明 在使用spring框架配置AOP的時候,不管是通過XML配置文件還是註解的方式都需要定義pointcut"切入點" 例如定義切入點表達式 execution(* com.sample.service.impl..*.*(..)) executi ...
  • 在網上找了很多方法,終於找到了一個,記錄之。 JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean(); factory.setServiceClass(Service1Soap.class);// 設置請求介面 factory.setA... ...
  • 1、錯誤類型:PHP致命錯誤 Error type: PHP Fatal error Fatal error: Cannot redeclare (a) (previously declared in (b)) in (c) on line (d) 2、錯誤描述: 該錯誤報告表示你正企圖對已經定義過 ...
  • urllib requets selenium的應用場景 cookie識別用戶身份和記錄用戶狀態 driver.get_cookies() 獲得cookie信息 add_cookie(cookie_dict) 向cookie添加會話信息 delete_cookie(name) 刪除特定(部分)的co ...
  • 上篇說到了 RabbitMQ 的安裝。 這次要在講案例之前,需要安裝PHP的AMQP擴展。不然可能會報以下兩個錯誤。 1.Fatal error: Class 'AMQPConnection' not found 2. Fatal error: Uncaught exception 'AMQPCon ...
  • RabbitMQ: 1、是實現AMQP(高級消息隊列協議)的消息中間件的一種。 2、主要是為了實現系統之間的雙向解耦而實現的。當生產者大量產生數據時,消費者無法快速消費,那麼需要一個中間層。保存這個數據。 一般提到 RabbitMQ 和消息,都會用到以下一些專有名詞: (1)生產(Producing ...
  • 閱讀目錄 前言 怎麼賣 領域服務的使用 回到現實 結語 閱讀目錄 前言 怎麼賣 領域服務的使用 回到現實 結語 一、前言 上篇中我們講述了“把商品賣給用戶”中的商品和用戶的初步設計。現在把剩餘的“賣”這個動作給做了。這裡提醒一下,正常情況下,我們的每一步業務設計都需要和領域專家進行溝通,儘可能的符合 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...