圖解Java設計模式之迭代器模式

来源:https://www.cnblogs.com/haizai/archive/2020/03/29/12593396.html
-Advertisement-
Play Games

圖解Java設計模式之迭代器模式 看一個具體的需求 傳統的方式的問題分析 迭代器模式基本介紹 迭代器模式的原理類圖 迭代器模式應用實例 迭代器模式在JDK - ArrayList 集合應用的源碼分析 迭代器模式的註意事項和細節 看一個具體的需求 編寫程式展示一個學校院繫結構 :需求是這樣,要在一個頁 ...


圖解Java設計模式之迭代器模式

 

看一個具體的需求

編寫程式展示一個學校院繫結構 :需求是這樣,要在一個頁面中展示出學校的院系組成,一個學校有多個學院,一個學院有多個系。如圖 :
在這裡插入圖片描述
在這裡插入圖片描述

傳統的方式的問題分析

1)將學院看做是學校的子類,系是學院的子類,這樣實際上是站在組織大小來進行分層次的。
2)實際上我們的要求是 :在一個頁面中展示出學校的院系組成,一個學校有多個學院,一個學院有多個系,因此這種方案,不能很好實現遍歷操作。

迭代器模式基本介紹

1)迭代器模式(Iterator Pattern)是常用的設計模式,屬於行為型模式
2)如果我們的集合元素是用不同的方式實現的,有數組,還有java的集合類,或者還有其他方式,當客戶端要遍歷這些集合元素的時候就要使用多種遍歷方式,而且還會暴露元素的內部結構,可以考慮使用迭代器模式解決。
3)迭代器模式,提供一種遍歷集合元素的統一介面,用一致的方法遍歷集合元素,不需要知道集合對象的底層表示,即 :不暴露其內部的結構。

迭代器模式的原理類圖

在這裡插入圖片描述
說明 :
1)Iterator :迭代器介面,是系統提供,含義 hasNext、next、remove
2)ConcreteIterator :具體的迭代器類,管理迭代。
3)Aggregate :一個統一的聚合介面,將客戶端和具體聚合解耦。
4)ConcreteAggreage :具體的聚合持有對象集合,並提供一個方法,返回一個迭代器,該迭代器可以正確遍歷集合
5)Client :客戶端,通過Iterator和Aggregate依賴子類。

迭代器模式應用實例

  1. 應用實例要求 編寫程式展示一個學校院繫結構:需求是這樣,要在一個頁面中展示出學校的院系組成,一個學校有多個學院, 一個學院有多個系。
    在這裡插入圖片描述
package com.example.demo.iterator;

import java.util.Iterator;

import javax.swing.text.Position;

public class ComputerCollegeIterator implements Iterator{
	
	// 這裡我們需要Department 是以怎樣的方式存放
	private Department[] departments;
	// 遍歷的位置
	private int position = 0;

	public ComputerCollegeIterator(Department[] departments) {
		super();
		this.departments = departments;
	}

	/**
	 * 判斷是否還有下一個元素
	 */
	@Override
	public boolean hasNext() {
		// TODO Auto-generated method stub
		if (departments.length <= position || departments[position] == null) {
			return false;
		}
		return true;
	}

	@Override
	public Object next() {
		// TODO Auto-generated method stub
		Department department = departments[position];
		position += 1;
		return department;
	}

}
package com.example.demo.iterator;

import java.util.Iterator;
import java.util.List;

public class InfoColleageIterator implements Iterator{
	
	/**
	 * 信息工程學院是以list方式存放系
	 */
	private List<Department> departmentList;
	
	/**
	 * 索引
	 */
	private int index = -1;
	
	public InfoColleageIterator(List<Department> departmentList) {
		super();
		this.departmentList = departmentList;
	}

	/**
	 * 判斷list中還有沒有下一個元素
	 */
	@Override
	public boolean hasNext() {
		// TODO Auto-generated method stub
		if (index >= departmentList.size() - 1) {
			return false;
		}
		index += 1;
		return true;
	}

	@Override
	public Object next() {
		// TODO Auto-generated method stub
		return departmentList.get(index);
	}
	
	/**
	 * remove空實現
	 */
	public void remove() {
		
	}

}
package com.example.demo.iterator;

/**
 * 系
 * @author zhaozhaohai
 *
 */
public class Department {
	
	private String name;
	
	private String desc;

	public Department(String name, String desc) {
		super();
		this.name = name;
		this.desc = desc;
	}

	public String getName() {
		return name;
	}

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

	public String getDesc() {
		return desc;
	}

	public void setDesc(String desc) {
		this.desc = desc;
	}
	
	

}
package com.example.demo.iterator;

import java.util.Iterator;

public interface College {
	
	public String getName();
	
	/**
	 * 增加系的方法
	 * @param name
	 * @param desc
	 */
	public void addDepartment(String name, String desc);
	
	/**
	 * 返回一個迭代器,遍歷
	 * @return
	 */
	public Iterator createIterator();

}
package com.example.demo.iterator;

import java.util.Iterator;

public class ComputerCollege implements College{
	
	private Department[] departments;
	// 保持當前數組的對象個數
	private int numOfDepartment = 0;
	
	public ComputerCollege() {
		departments = new Department[5];
		addDepartment("java", "java");
		addDepartment("前端", "前端");
		addDepartment("大數據", "大數據");
	}

	@Override
	public String getName() {
		// TODO Auto-generated method stub
		return "電腦學院";
	}

	@Override
	public void addDepartment(String name, String desc) {
		// TODO Auto-generated method stub
		Department department = new Department(name, desc);
		departments[numOfDepartment] = department;
		numOfDepartment += 1;
	}

	@Override
	public Iterator createIterator() {
		// TODO Auto-generated method stub
		return new ComputerCollegeIterator(departments);
	}

}
package com.example.demo.iterator;

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

public class InfoCollege implements College{
	
	private List<Department> departmentList;
	
	public InfoCollege() {
		departmentList = new ArrayList<Department>();
		addDepartment(" 信息安全專業 ", "信息安全專業");
		addDepartment("網路安全專業", "網路安全專業");
		addDepartment("工程安全專業", "工程安全專業");
	}

	@Override
	public String getName() {
		// TODO Auto-generated method stub
		return "信息工程學院";
	}

	@Override
	public void addDepartment(String name, String desc) {
		// TODO Auto-generated method stub
		Department department = new Department(name, desc);
		departmentList.add(department);
	}

	@Override
	public Iterator createIterator() {
		// TODO Auto-generated method stub
		return new InfoColleageIterator(departmentList);
	}

}
package com.example.demo.iterator;

import java.util.Iterator;
import java.util.List;

public class OutPutImpl {
	
	
	// 學院集合
	private List<College> colleges;
	
	public OutPutImpl(List<College> colleges) {
		super();
		this.colleges = colleges;
	}
	
	/**
	 * 遍歷所有學院,然後調用printDepartment 輸出各個學院的系
	 */
	public void printCollege() {
		// 從collegeList 取出所有學院,Java中的list 已經實現Iterator
		Iterator iterator = colleges.iterator();
		while (iterator.hasNext()) {
			// 取出一個學院
			College college = (College) iterator.next();
			System.out.println("====" + college.getName() + "====");
			printDepartment(college.createIterator());
		}
	}

	/**
	 * 輸出學院里的系
	 * @param iterator
	 */
	public void printDepartment(Iterator iterator) {
		while (iterator.hasNext()) {
			Department department = (Department)iterator.next();
			System.out.println(department.getName());
		}
	}

}
package com.example.demo.iterator;

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

public class Client {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		// 創建學院
		List<College> colleges = new ArrayList<College>();
		ComputerCollege college = new ComputerCollege();
		InfoCollege infoCollege = new InfoCollege();
		colleges.add(college);
		//colleges.add(infoCollege);
		OutPutImpl outPutImpl = new OutPutImpl(colleges);
		outPutImpl.printCollege();
	}

}

迭代器模式在JDK - ArrayList 集合應用的源碼分析

在這裡插入圖片描述
在這裡插入圖片描述
在這裡插入圖片描述
在這裡插入圖片描述
對類圖的角色分析和說明 :
1)內部類Itr 充當具體實現迭代器 Iterator 的類,作為ArrayList 內部類
2)Lits 就是充當類聚合介面,含有一個Iterator() 方法,返回一個迭代器對象
3)ArrayList 是實現聚合介面 List 的子類,實現類iterator()
4)Iterator 介面系統提供
5)迭代器模式解決了,不同集合(ArrayList,LinkedList)統一遍歷問題

迭代器模式的註意事項和細節

優點 :
1)提供一個統一的方法遍歷對象,客戶不用再考慮聚合的類型,使用一種方法就可以遍歷對象了。
2)隱藏了聚合的內部結構,客戶端要遍歷聚合的時候只能取到迭代器,而不會知道聚合的具體組成。
3)提供了一種設計思想,就是一個類應該只有一個引起變化的原因(叫做單一職責原則)。在聚合類中,我們把迭代器分開,就是要把管理對象集合和遍歷對象集合的責任分開,這樣一來集合改變的話,隻影響到聚合對象。而如果遍歷方式改變的話,隻影響到了迭代器。
4)當要展示一組相似對象,或者遍歷一組相同對象時使用,適合使用迭代器模式。
缺點 :
1)每個聚合對象都要一個迭代器,會生成多個迭代器不好管理類。


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

-Advertisement-
Play Games
更多相關文章
  • 1 <div style="width: 50%"> 2 <table class="layui-table"> 3 <tbody> 4 <tr> 5 <td>Bud</td> 6 <td>179</td> 7 <td>183</td> 8 <td>44</td> 9 <td>37</td> 10 ...
  • 1、ThymeLeaf+LayUI表格渲染錯誤 使用thymeleafhe+layui渲染表格時,出現錯誤org.thymeleaf.exceptions.TemplateProcessingException: Could not parse as expression: 這是因為[[]]是thy ...
  • 將指定數字插入到數組的末尾,返回值為 將數組的第一個元素刪除並返回,返回值為 ...
  • 簡單繼承: @extend 繼承 編譯後 關聯屬性繼承: 編譯後 鏈式繼承: 編譯後 偽類繼承: 編譯後 sass嵌套 編譯後 相同的屬性值首碼,也可以用嵌套 編譯後 sass條件控制 @if @else if @else 編譯後 條件判斷語句也可以寫在外面 編譯後 迴圈 @for $i from ...
  • 對前端稍微有點瞭解的初學者都知道,JavaScript是必不可少的工具。毫不誇張的說,大部分網頁都使用了JavaScript,想要成為一個優秀的前端工程師,做出漂亮令用戶滿意的網頁,熟練掌握JavaScript是一個必備技能。本文為新手整理了一篇JavaScript基礎教程入門指南,希望可以幫助編程 ...
  • number類型 編譯後 color類型: 編譯後 string類型 編譯後 list數組類型 nth(list, num) 獲取list數組中的下標為num的元素 註意num下標是從1開始的 編譯後 index(list, str) 返回str在list數組中的下標 編譯後 map 數組類型(有點 ...
  • 當網路中兩個進程需要通信時,我們往往會使用 來實現。 都不陌生。當三次握手成功後,客戶端與服務端就能通信,並且,彼此之間通信的數據包格式都是二進位,由 協議負責傳輸。 當客戶端和服務端取得了二進位數據包後,我們往往需要『萃取』出想要的數據,這樣才能更好的執行業務邏輯。所以,我們需要定義好數據結構來描 ...
  • 腳本的生成過程 添加模板的時候生成script,商家添加商品的時候拷貝相應的script到sku中。 更新運費模板的時候,發消息到消費者,批量更新相關sku的模板信息。 計算過程 緩存數據結構 script和模板id作為sku的一部分存儲是為了計算使用相同模板的sku的總價。 腳本示例 functi ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...