JDK源碼——利用模板方法看設計模式

前言:

相信很多人都聽過一個問題:把大象關進冰箱門,需要幾步?

第一,把冰箱門打開;第二,把大象放進去;第三,把冰箱門關上。我們可以看見,這個問題的答案回答的很有步驟。接下來我們介紹一種設計模式——模板方法模式,你會發現,它與這個問題的答案實際上有很多共同之處。

一、定義

定義一個算法骨架,允許子類為一個或多個步驟提供實現。模板方法使得子類可以在不改變算法結構的情況下,重新定義算法的某些步驟。

二、適用場景

一次性實現一個算法的不變的部分,將可變的行為留給子類實現

也就是將各子類中公共行為被提取出來并集中到一個公共父類中,從而避免代碼重復。還是拿上面大象放進冰箱里面的例子,打開冰箱和關上冰箱都是不變的行為,我們可以將其放在公共父類實現。但是放大象,怎么放?是先放背對著冰箱放,還是面對著冰箱放。不想放大象,放老虎或者其他動物呢?這些就是我們可變的行為,這個就放入子類中實現。可以說,模板方法提供了一個很好的代碼復用平臺

三、JDK中的模板方法模式

在剛接觸ArrayList的時候一直沒注意它繼承的類和實現的接口。直到現在講到了模板方法模式,再去看ArrayList的時候能明白不少。在前面的博客中有提到List接口和Cloneable接口是用來實現什么設計模式的。今天就來看看這個ArrayList的父類AbstractList。

AbstractList就是我們前面適用場景中介紹的父類(也叫模板類),這個類里面即提供了公共的方法(不可供子類修改),又提供了可讓子類修改的方法。下面我們直接看源碼,由于方法很多,我們就介紹一下addAll方法。

public abstract class AbstractList<E> extends AbstractCollection<E> implements List<E> {public Boolean addAll(int index, Collection<? extends E> c) {rangeCheckForAdd(index);Boolean modified = false;for (E e : c) {add(index++, e);modified = true;}return modified;}
}
復制代碼

上面的是AbstractList的addAll方法,可以看見這個方法沒有限定子類是否去修改,子類由需要就去修改,如果子類不想修改,完全能夠按照AbstractList中的邏輯添加元素。事實上我看了一遍AbstractList中的方法發現除了一些私有的方法不能給子類給子類訪問之外,其余的基本上都是可以給子類去選擇是否修改的。如果子類覺得父類的方法可行,那么直接使用父類的方法即可。

public class ArrayList<E> extends AbstractList<E>implements List<E>, RandomAccess, Cloneable, java.io.Serializable
{public boolean addAll(int index, Collection<? extends E> c) {rangeCheckForAdd(index);Object[] a = c.toArray();int numNew = a.length;ensureCapacityInternal(size + numNew);  // Increments modCountint numMoved = size - index;if (numMoved > 0)System.arraycopy(elementData, index, elementData, index + numNew,numMoved);System.arraycopy(a, 0, elementData, index, numNew);size += numNew;return numNew != 0;}
}
復制代碼

上面這個就是ArrayList中的addAll方法。

但是AbstractList里面有一個方法,就是get()方法,AbstractList明確要求要讓子類實現。由于代碼較少,我就直接截圖

左邊是父類AbstractList中的,右邊是ArrayList中的方法。在父類中沒有直接寫出實現代碼,而是讓子類自己手動去實現。除此之外其實還有一個方法就是AbstractList父類AbstractCollection中的toString方法。在ArrayList中是沒有的,但是平常在寫代碼時候,是可以直接調用的,這就是一個公共的方法。

四、總結

模板方法模式只需要簡單的繼承關系就可以完成。相信平常我們在寫代碼的時候也是使用過模板方法模式,只是我們并不知道是這種設計模式。這里多說一下,如果我們希望子類不要修改父類的方法,只需要加上final修飾即可;如果希望子類一定重寫父類的方法,就將父類的方法用abstract修飾;如果子類可以修改也可以不修改,就可以像addAll方法那樣設計即可。重點理解模板,這個模板盡量使用抽象類。因為抽象類比接口更加的靈活,能將模板定義的更好。其實看完上面的源碼解析,總結起來就是一句話AbstractList是ArrayList的模板。

讀者福利

怎么提高代碼質量?——來自阿里P8架構師的研發經驗總結

阿里P8分享Java架構師的學習路線,第六點尤為重要

每個Java開發者應該知道的八個工具

想面試Java架構師?這些最基本的東西你都會了嗎?

畫個圖來找你的核心競爭力,變中年危機為加油站

哪有什么中年危機,不過是把定目標當成了有計劃

被裁員不是寒冬重點,重點是怎么破解職業瓶頸

轉載于:https://juejin.im/post/5cc1372de51d456e7618a6f1

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/251854.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/251854.shtml
英文地址,請注明出處:http://en.pswp.cn/news/251854.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

[Usaco2010 Mar]gather 奶牛大集會

1827: [Usaco2010 Mar]gather 奶牛大集會 Time Limit: 1 Sec Memory Limit: 64 MB Submit: 1129 Solved: 525 [Submit][Status][Discuss]Description Bessie正在計劃一年一度的奶牛大集會&#xff0c;來自全國各地的奶牛將來參加這一次集會。當然&#xff0c;她會選擇最方便的…

與TIME_WAIT相關的幾個內核參數

問題 公司用瀏覽器訪問線上服務一會失敗一會成功&#xff0c;通過ssh連接服務器排查時發現ssh也是這樣&#xff1b; 檢查 抓包后發現建立連接的請求已經到了服務器&#xff0c;但它沒有響應&#xff1b; 糾結了好久&#xff0c;后來在騰訊云技術支持及查了相關資料后發現是開啟…

View的繪制-layout流程詳解

目錄 作用 根據 measure 測量出來的寬高&#xff0c;確定所有 View 的位置。 具體分析 View 本身的位置是通過它的四個點來控制的&#xff1a; 以下涉及到源碼的部分都是版本27的&#xff0c;為方便理解觀看&#xff0c;代碼有所刪減。 layout 的流程 先通過 measure 測量出 Vi…

1-1、作用域深入和面向對象

課時1&#xff1a;預解釋 JS中的數據類型 number、string、 boolean、null、undefined JS中引用數據類型 object: {}、[]、/^$/、Date Function var num12; var obj{name:白鳥齊鳴,age:10}; function fn(){ console.log(勿忘初心方得始終&#xff01;) }console.log(fn);//把整…

茶杯頭開槍ahk代碼

;說明這個工具是為了茶杯頭寫的,F1表示換槍攻擊,F3表示不換槍攻擊,F2表示停止攻擊. $F1::loop{ GetKeyState, state, F2, Pif state D{break } Send, {l down}Send, {l up}sleep,10Send,{m down}Send,{m up} }return $F3::loop{ GetKeyState, state, F2, Pif state D{break }…

Vim使用技巧:撤銷與恢復撤銷

在使用VIM的時候&#xff0c;難免會有輸錯的情況&#xff0c;這個時候我們應該如何撤銷&#xff0c;然后回到輸錯之前的狀態呢&#xff1f;答案&#xff1a;使用u&#xff08;小寫&#xff0c;且在命令模式下&#xff09;命令。 但如果有時我們一不小心在命令模式下輸入了u&…

PaddlePaddle開源平臺的應用

最近接觸了百度的開源深度學習平臺PaddlePaddle&#xff0c;想把使用的過程記錄下來。 作用&#xff1a;按照這篇文章&#xff0c;能夠實現對圖像的訓練和預測。我們準備了四種顏色的海洋球數據&#xff0c;然后給不同顏色的海洋球分類為0123四種。 一、安裝paddlepaddle 1.系統…

Hyperledger Fabric區塊鏈工具configtxgen配置configtx.yaml

configtx.yaml是Hyperledger Fabric區塊鏈網絡運維工具configtxgen用于生成通道創世塊或通道交易的配置文件&#xff0c;configtx.yaml的內容直接決定了所生成的創世區塊的內容。本文將給出configtx.yaml的詳細中文說明。 如果需要快速掌握Fabric區塊鏈的鏈碼與應用開發&#x…

js閉包??

<script>var name "The Window";var object {name : "My Object",getNameFunc : function(){console.log("11111");console.log(this); //this object //調用該匿名函數的是對象return function(){console.log("22222");co…

JavaScript----BOM(瀏覽器對象模型)

BOM 瀏覽器對象模型 BOM 的全稱為 Browser Object Model,被譯為瀏覽器對象模型。BOM提供了獨立于 HTML 頁面內容&#xff0c;而與瀏覽器相關的一系列對象。主要被用于管理瀏覽器窗口及與瀏覽器窗口之間通信等功能。 1、Window 對象 window對象是BOM中最頂層對象&#xff1b;表示…

JWT協議學習筆記

2019獨角獸企業重金招聘Python工程師標準>>> 官方 https://jwt.io 英文原版 https://www.ietf.org/rfc/rfc7519.txt 或 https://tools.ietf.org/html/rfc7519 中文翻譯 https://www.jianshu.com/p/10f5161dd9df 1. 概述 JSON Web Token&#xff08;JWT&#xff09;是…

DOM操作2

一、API和WebAPI API就是接口&#xff0c;就是通道&#xff0c;負責一個程序和其他軟件的溝通&#xff0c;本質是預先定義的函數。Web API是網絡應用程序接口。包含了廣泛的功能&#xff0c;網絡應用通過API接口&#xff0c;可以實現存儲服務、消息服務、計算服務等能力&#x…

浮動布局demo

<!DOCTYPE html> <html><head><meta charset"UTF-8"><title>浮動布局</title><style type"text/css">*{margin: 0;padding: 0;}header{height: 150px;background: yellow;}nav{height: 30px;background: green;…

UI行業發展預測 系列規劃的調整

我又雙叒叕拖更了&#xff0c;上一篇還是1月22號更新的&#xff0c;這都3月9號了……前面幾期把職業規劃、能力分析、幾個分析用的設計理論都寫完了&#xff0c;當然實際工作中用到的方法論不止上面這些&#xff0c;后續會接著學習&#xff1b;如果你的目標是一線團隊&#xff…

出現Press ENTER or type command to continue的原因

cd 然后 vim .vimrc 寫入 set nu 保存 退出轉載于:https://www.cnblogs.com/520qtf/p/8968441.html

基于Flask實現后臺權限管理系統 - 導言

網上有這樣一個段子&#xff0c;在評論語言好壞的時候&#xff0c;都會有人評論說PHP是世界上最好的語言&#xff0c;人生苦短我用Python&#xff0c;這里姑且不去評論語言的好壞&#xff0c;每一個語言存在都有它的價值&#xff0c;譬如C語言適合底層開發&#xff0c;整個Linu…

5-1 unittest框架使用

unittest是python的一個單元測試框架&#xff0c;內置的&#xff0c;不需要pip install 什么什么的。直接在py文件里面調用 import unittest。 他這個框架是怎么回事呢&#xff0c;他可以對數據初始化&#xff0c;然后執行測試&#xff08;里面有斷言功能就是判斷返回是否正確…

bzoj 4573: [Zjoi2016]大森林

Description 小Y家里有一個大森林&#xff0c;里面有n棵樹&#xff0c;編號從1到n。一開始這些樹都只是樹苗&#xff0c;只有一個節點&#xff0c;標號為1。這些樹 都有一個特殊的節點&#xff0c;我們稱之為生長節點&#xff0c;這些節點有生長出子節點的能力。小Y掌握了一種魔…

Unity3D在C#編程中的一些命名空間的引用及說明

System包含用于定義常用值和引用數據類型、事件和事件處理程序、接口、屬性和處理異常的基礎類和基類。其他類提供支持下列操作的服務&#xff1a;數據類型轉換&#xff0c;方法參數操作&#xff0c;數學計算&#xff0c;遠程和本地程序調用&#xff0c;應用程序環境管理以及對…

docker入門簡介

簡介docker(容器技術)是實現虛擬化技術的一種方案,通過利用linux中命名空間,控制組和聯合文件系統這個三個主要技術,來實現應用程序空間的隔離.通過對應用程序運行環境的封裝來生成鏡像并部署來實現跨平臺,一定程度上加快了服務交付的整體流程.這篇文章主要介紹docker的一些基本…