1.說一下開發中需要遵守的設計原則?
設計模式中主要有六大設計原則,簡稱為SOLID ,是由于各個原則的首字母簡稱合并的來(兩個L算一個,solid 穩定的),六大設計原則分別如下:
1、單一職責原則
單一職責原則的定義描述非常簡單,也不難理解。一個類只負責完成一個職責或者功能。也就是說在類的設計中 我們不要設計大而全的類,而是要設計粒度小、功能單一的類。
比如 我們設計一個類里面既包含了用戶的一些操作,又包含了支付的一些操作,那這個類的職責就不夠單一,應該將該類進行拆分,拆分成多個功能更加單一的,粒度更細的類.
2、開放封閉原則
定義:對擴展開放,對修改關閉
對擴展開放和對修改關閉表示當一個類或一個方法有新需求或者需求發生改變時應該采用擴展的方式而不應該采用修改原有邏輯的方式來實現。因為擴展了新的邏輯如果有問題只會影響新的業務,不會影響老業務;而如果采用修改的方式,很有可能就會影響到老業務受影響。
優點:
- 新老邏輯解耦,需求發生改變不會影響老業務的邏輯
- 改動成本最小,只需要追加新邏輯,不需要改的老邏輯
- 提供代碼的穩定性和可擴展性
3、里氏替換原則
要理解里氏替換原則,其實就是要理解兩個問題:
- 什么是替換?
- 什么是與期望行為一致的替換(Robert Martin所說的“必須能夠替換”)?
1 ) 什么是替換 ?
替換的前提是面向對象語言所支持的多態特性,同一個行為具有多個不同表現形式或形態的能力。
以JDK的集合框架為例,
List
接口的定義為有序集合,List
接口有多個派生類,比如大家耳熟能詳的ArrayList
,LinkedList
。那當某個方法參數或變量是List
接口類型時,既可以是ArrayList
的實現, 也可以是LinkedList
的實現,這就是替換。
2 ) 什么是與期望行為一致的替換?
在不了解派生類的情況下,僅通過接口或基類的方法,即可清楚的知道方法的行為,而不管哪種派生類的實現,都與接口或基類方法的期望行為一致。
不需要關心是哪個類對接口進行了實現,因為不管底層如何實現,最終的結果都會符合接口中關于方法的描述(也就是與接口中方法的期望行為一致).
或者說接口或基類的方法是一種契約,使用方按照這個契約來使用,派生類也按照這個契約來實現。這就是與期望行為一致的替換。
4、接口隔離原則
定義:要為各個類建立它們需要的專用接口,而不要試圖去建立一個很龐大的接口供所有依賴它的類去調用。
接口隔離原則與單一職責原則的區別
接口隔離原則和單一職責都是為了提高類的內聚性、降低它們之間的耦合性,體現了封裝的思想,但兩者是不同的:
- 單一職責原則注重的是職責,而接口隔離原則注重的是對接口依賴的隔離。
- 單一職責原則主要是約束類,它針對的是程序中的實現和細節;接口隔離原則主要約束接口,主要針對抽象和程序整體框架的構建。
5、依賴倒置原則
定義:依賴倒置原則(Dependence Inversion Principle,DIP)是指在設計代碼架構時,高層模塊不應該依賴于底層模塊,二者都應該依賴于抽象。抽象不應該依賴于細節,細節應該依賴于抽象。
依賴倒置原則是實現開閉原則的重要途徑之一,它降低了客戶與實現模塊之間的耦合。
依賴倒置原則的好處:
- 減少類間的耦合性,提高系統的穩定性 . (根據類與類之間的耦合度從弱到強排列:依賴關系、關聯關系、聚合關系、組合關系、泛化關系和實現關系 )
- 降低并行開發引起的風險 (兩個類之間有依賴關系,只要制定出兩者之間的接口(或抽象類)就可以獨立開發了)
- 提高代碼的可讀性和可維護性
6、迪米特法則
簡單來說迪米特法則想要表達的思想就是: 不該有直接依賴關系的類之間,不要有依賴;有依賴關系的類之間,盡量只依賴必要的接口。
如果兩個軟件實體無須直接通信,那么就不應當發生直接的相互調用,可以通過第三方轉發該調用。其目的是降低類之間的耦合度,提高模塊的相對獨立性。
軟件開發中我們要基于這六個原則,設計建立穩定、靈活、健壯的程序.
2.什么是設計模式?使用過設計模式嗎?
設計模式(Design pattern)是一套被反復使用、多數人知曉的、經過分類編目的、代碼設計經驗的總結
在GOF編寫的設計模式(可復用面向對象軟件的基礎)一書中說道: 本書涉及的設計模式并不描述新的或未經證實的設計,我們只收錄那些在不同系統中多次使用過的成功設計。
大部分設計模式要解決的都是代碼的可重用性、可擴展性問題
如果說數據結構和算法是教你如何寫出高效代碼,那設計模式講的是如何寫出可擴展、可讀、可維護的高質量代碼,所以,它們跟平時的編碼會有直接的關系,也會直接影響到你的開發能力。
設計模式的好處
- 不再編寫 bullshit-code
- 提高復雜代碼的設計和開發能力
- 有助于我們讀懂源碼,學習框架更加事半功倍
GoF設計模式只有23個,但是它們各具特色 ,每個模式都為某一個可重復的設計問題提供了一套解決方案。
根據它們的用途,設計模式可分為 創建型(Creational) ,結構型(Structural) 和行為型(Behavioral)
創建型模式(5種):提供創建對象的機制,提升已有代碼的靈活性和可復用性
- 常用的有:單例模式、工廠模式(工廠方法和抽象工廠)、建造者模式。
- 不常用的有:原型模式。
結構型模式(7種):介紹如何將對象和類組裝成較大的結構,并同時保持結構的靈活和高效
- 常用的有:代理模式、橋接模式、裝飾者模式、適配器模式。
- 不常用的有:門面模式、組合模式、享元模式。
行為模式(11種):負責對象間的高效溝通和職責傳遞委派
- 常用的有:觀察者模式、模板模式、策略模式、職責鏈模式、迭代器模式、狀態模式。
- 不常用的有:訪問者模式、備忘錄模式、命令模式、解釋器模式、中介模式。
3.說一下單例模式,及其應用場景?
定義
單例模式(Singleton Pattern)是 Java 中最簡單的設計模式之一,此模式保證某個類在運行期間,只有一個實例對外提供服務,而這個類被稱為單例類。
單例模式也比較好理解,比如一個人一生當中只能有一個真實的身份證號,一個國家只有一個政府,類似的場景都是屬于單例模式。
使用單例模式要做的兩件事
- 保證一個類只有一個實例
- 為該實例提供一個全局訪問節點
單例模式結構
單例的實現
- 餓漢式
- 懶漢式
- 雙重檢測
- 靜態內部類
- 枚舉方式
應用場景
- 資源共享的情況下,避免由于資源操作時導致的性能或損耗等。如上述中的日志文件,應用配置。
- 控制資源的情況下,方便資源之間的互相通信。如線程池等。
4.介紹一下代理模式的種類和它們之間區別?
1)靜態代理
這種代理方式需要代理對象和目標對象實現一樣的接口。
- 優點:可以在不修改目標對象的前提下擴展目標對象的功能。
- 缺點:
- 冗余。由于代理對象要實現與目標對象一致的接口,會產生過多的代理類。
- 不易維護。一旦接口增加方法,目標對象與代理對象都要進行修改。
2)JDK動態代理
動態代理利用了JDK API,動態地在內存中構建代理對象,從而實現對目標對象的代理功能.動態代理又被稱為JDK代理或接口代理.
靜態代理與動態代理的區別:
- 靜態代理在編譯時就已經實現了,編譯完成后代理類是一個實際的class文件
- 動態代理是在運行時動態生成的,即編譯完成后沒有實際的class文件,而是在運行時動態生成類字節碼,并加載到JVM中.
3)CGLIB 動態代理
cglib (Code Generation Library ) 是一個第三方代碼生成類庫,運行時在內存中動態生成一個子類對象從而實現對目標對象功能的擴展。cglib 為沒有實現接口的類提供代理,為JDK的動態代理提供了很好的補充。
- 最底層是字節碼
- ASM是操作字節碼的工具
- cglib基于ASM字節碼工具操作字節碼(即動態生成代理,對方法進行增強)
- SpringAOP基于cglib進行封裝,實現cglib方式的動態代理
4)三種代理模式實現方式的對比
-
jdk代理和CGLIB代理
使用CGLib實現動態代理,CGLib底層采用ASM字節碼生成框架,使用字節碼技術生成代理類,在JDK1.6之前比使用Java反射效率要高。唯一需要注意的是,CGLib不能對聲明為final的類或者方法進行代理,因為CGLib原理是動態生成被代理類的子類。
在JDK1.6、JDK1.7、JDK1.8逐步對JDK動態代理優化之后,在調用次數較少的情況下,JDK代理效率高于CGLib代理效率,只有當進行大量調用的時候,JDK1.6和JDK1.7比CGLib代理效率低一點,但是到JDK1.8的時候,JDK代理效率高于CGLib代理。所以如果有接口使用JDK動態代理,如果沒有接口使用CGLIB代理。
-
動態代理和靜態代理
動態代理與靜態代理相比較,最大的好處是接口中聲明的所有方法都被轉移到調用處理器一個集中的方法中處理(InvocationHandler.invoke)。這樣,在接口方法數量比較多的時候,我們可以進行靈活處理,而不需要像靜態代理那樣每一個方法進行中轉。
如果接口增加一個方法,靜態代理模式除了所有實現類需要實現這個方法外,所有代理類也需要實現此方法。增加了代碼維護的復雜度。而動態代理不會出現該問題
5.工廠模式有哪幾種,之間有什么區別?
在工廠模式中,我們在創建對象時不會對客戶端暴露創建邏輯,并且是通過使用一個共同的接口來指向新創建的對象。
《設計模式》一書中,工廠模式被分為了三種:簡單工廠、工廠方法和抽象工廠。(不過,在書中作者將簡單工廠模式看作是工廠方法模式的一種特例。
1)簡單工廠模式
簡單工廠不是一種設計模式,反而比較像是一種編程習慣。簡單工廠模式又叫做靜態工廠方法模式(static Factory Method pattern),它是通過使用靜態方法接收不同的參數來返回不同的實例對象.
實現方式: 定義一個工廠類,根據傳入的參數不同返回不同的實例,被創建的實例具有共同的父類或接口。
適用場景:
(1)需要創建的對象較少。
(2)客戶端不關心對象的創建過程。
優點:
- 封裝了創建對象的過程,可以通過參數直接獲取對象。把對象的創建和業務邏輯層分開,這樣以后就避免了修改客戶代碼,如果要實現新產品直接修改工廠類,而不需要在原代碼中修改,這樣就降低了客戶代碼修改的可能性,更加容易擴展。
缺點:
- 增加新產品時還是需要修改工廠類的代碼,違背了“開閉原則”。
2)工廠方法模式
工廠方法模式 Factory Method pattern
,屬于創建型模式.
概念: 定義一個用于創建對象的接口,讓子類決定實例化哪個產品類對象。工廠方法使一個產品類的實例化延遲到其工廠的子類。
工廠方法模優缺點
優點:
- 用戶只需要知道具體工廠的名稱就可得到所要的產品,無須知道產品的具體創建過程;
- 在系統增加新的產品時只需要添加具體產品類和對應的具體工廠類,無須對原工廠進行任何修改,滿足開閉原則;
缺點:
- 每增加一個產品就要增加一個具體產品類和一個對應的具體工廠類,這增加了系統的復雜度。
3)抽象工廠模式
抽象工廠模式(Abstract Factory Pattern)屬于創建型模式,它實際上是對工廠方法模式的擴展,相當于一個超級工廠,用于創建其他工廠的模式。
在抽象工廠模式中,接口是負責創建一個相關對象的工廠,而且每個工廠都能按照工廠模式提供對象。其實抽象工廠也是為了減少工廠方法中的子類和工廠類數量,基于此提出的設計模式。
在抽象工廠模式中,每一個具體工廠都提供了多個工廠方法,用于產生多種不同類型的產品
抽象工廠模式優點
- 對于不同產品系列有比較多共性特征時,可以使用抽象工廠模式,有助于提升組件的復用性.
- 當需要提升代碼的擴展性并降低維護成本時,把對象的創建和使用過程分開,能有效地將代碼統一到一個級別上
- 解決跨平臺帶來的兼容性問題
抽象工廠模式缺點
- 增加新的產品等級結構麻煩,需要對原有結構進行較大的修改,甚至需要修改抽象層代碼,這顯然會帶來較大不變,違背了開閉原則.
6.介紹一下觀察者設計模式?
觀察者模式(observer pattern)的原始定義是:定義對象之間的一對多依賴關系,這樣當一個對象改變狀態時,它的所有依賴項都會自動得到通知和更新。
解釋一下上面的定義: 觀察者模式它是用于建立一種對象與對象之間的依賴關系,一個對象發生改變時將自動通知其他對象,其他對象將相應的作出反應.
在觀察者模式中發生改變的對象稱為觀察目標,而被通知的對象稱為觀察者,一個觀察目標可以應對多個觀察者,而且這些觀察者之間可以沒有任何相互聯系,可以根據需要增加和刪除觀察者,使得系統更易于擴展.
觀察者模式的別名有發布-訂閱(Publish/Subscribe)模式,模型-視圖(Model-View)模式、源-監聽(Source-Listener) 模式等
觀察者模式結構中通常包括: 觀察目標和觀察者兩個繼承層次結構.
在觀察者模式中有如下角色:
- Subject:抽象主題(抽象被觀察者),抽象主題角色把所有觀察者對象保存在一個集合里,每個主題都可以有任意數量的觀察者,抽象主題提供一個接口,可以增加和刪除觀察者對象。
- ConcreteSubject:具體主題(具體被觀察者),該角色將有關狀態存入具體觀察者對象,在具體主題的內部狀態發生改變時,給所有注冊過的觀察者發送通知。
- Observer:抽象觀察者,是觀察者的抽象類,它定義了一個更新接口,使得在得到主題更改通知時更新自己。
- ConcrereObserver:具體觀察者,實現抽象觀察者定義的更新接口,以便在得到主題更改通知時更新自身的狀態。在具體觀察者中維護一個指向具體目標對象的引用,它存儲具體觀察者的有關狀態,這些狀態需要與具體目標保持一致.
觀察者模式的優點
- 降低了目標與觀察者之間的耦合關系,兩者之間是抽象耦合關系。
- 被觀察者發送通知,所有注冊的觀察者都會收到信息【可以實現廣播機制】
觀察者模式的缺點
- 如果觀察者非常多的話,那么所有的觀察者收到被觀察者發送的通知會耗時比較多
- 如果被觀察者有循環依賴的話,那么被觀察者發送通知會使觀察者循環調用,會導致系統崩潰
觀察者模式常見的使用場景
- 當一個對象狀態的改變需要改變其他對象時。比如,商品庫存數量發生變化時,需要通知商品詳情頁、購物車等系統改變數量。
- 一個對象發生改變時只想要發送通知,而不需要知道接收者是誰。比如,訂閱微信公眾號的文章,發送者通過公眾號發送,訂閱者并不知道哪些用戶訂閱了公眾號。
- 需要創建一種鏈式觸發機制時。比如,在系統中創建一個觸發鏈,A 對象的行為將影響 B 對象,B 對象的行為將影響 C 對象……這樣通過觀察者模式能夠很好地實現。
- 微博或微信朋友圈發送的場景。這是觀察者模式的典型應用場景,一個人發微博或朋友圈,只要是關聯的朋友都會收到通知;一旦取消關注,此人以后將不會收到相關通知。
7.裝飾器模式與代理模式的區別?
1)代理模式(Proxy Design Pattern ) 原始定義是:讓你能夠提供對象的替代品或其占位符。代理控制著對于原對象的訪問,并允許將請求提交給對象前后進行一些處理。
代理模式的適用場景
- 功能增強
當需要對一個對象的訪問提供一些額外操作時,可以使用代理模式 - 遠程(Remote)代理
實際上,RPC 框架也可以看作一種代理模式,GoF 的《設計模式》一書中把它稱作遠程代理。通過遠程代理,將網絡通信、數據編解碼等細節隱藏起來。客戶端在使用 RPC 服務的時候,就像使用本地函數一樣,無需了解跟服務器交互的細節。除此之外,RPC 服務的開發者也只需要開發業務邏輯,就像開發本地使用的函數一樣,不需要關注跟客戶端的交互細節。 - 防火墻(Firewall)代理
當你將瀏覽器配置成使用代理功能時,防火墻就將你的瀏覽器的請求轉給互聯網;當互聯網返回響應時,代理服務器再把它轉給你的瀏覽器。 - 保護(Protect or Access)代理
控制對一個對象的訪問,如果需要,可以給不同的用戶提供不同級別的使用權限。
2)裝飾器模式(decorator pattern) 的原始定義是:動態的給一個對象添加一些額外的職責. 就擴展功能而言,裝飾器模式提供了一種比使用子類更加靈活的替代方案.
裝飾器模式的適用場景
- 快速動態擴展和撤銷一個類的功能場景。 比如,有的場景下對 API 接口的安全性要求較高,那么就可以使用裝飾模式對傳輸的字符串數據進行壓縮或加密。如果安全性要求不高,則可以不使用。
- 不支持繼承擴展類的場景。 比如,使用 final 關鍵字的類,或者系統中存在大量通過繼承產生的子類。
裝飾器模式與代理模式的區別
對裝飾器模式來說,裝飾者(decorator)和被裝飾者(decoratee)都實現同一個 接口。
對代理模式來說,代理類(proxy class)和真實處理的類(real class)都實現同一個接口。
他們之間的邊界確實比較模糊,兩者都是對類的方法進行擴展,具體區別如下:
- 裝飾器模式強調的是增強自身,在被裝飾之后你能夠在被增強的類上使用增強后的功能。增強后你還是你,只不過能力更強了而已;代理模式強調要讓別人幫你去做一些本身與你業務沒有太多關系的職責(記錄日志、設置緩存)。代理模式是為了實現對象的控制,因為被代理的對象往往難以直接獲得或者是其內部不想暴露出來。
- 裝飾模式是以對客戶端透明的方式擴展對象的功能,是繼承方案的一個替代方案;代理模式則是給一個對象提供一個代理對象,并由代理對象來控制對原有對象的引用;
- 裝飾模式是為裝飾的對象增強功能;而代理模式對代理的對象施加控制,但不對對象本身的功能進行增強;
8.JDK 類庫常用的設計模式有哪些?
1)抽象工廠
- javax.xml.parsers.DocumentBuilderFactory抽象類
- public static DocumentBuilderFactory newInstance()方法
- 類功能:使得應用程序可以通過XML文件,獲得一個能生成DOM對象的解析器。
- 方法功能:獲取一個DocumentBuilderFactory的新實例。這一靜態方法會創建一個新的工廠實例。
2)建造者模式
- java.lang.StringBuilder,這是一個final類。
- public StringBuilder append(String str)方法,這一方法是對父類的覆寫。
- 類功能:用于一個不可更改的字符序列。
- 方法功能:根據現有字符序列和追加字符,通過系統拷貝方法System.arraycopy生成一個新的字符序列。
3)工廠模式
- java.text.NumberFormat抽象類。
- public final static NumberFormat getInstance()方法。
- 類功能:用于數字格式的抽象基類。
- 方法功能:返回一個“對當前默認場景下的一個通用數字格式”的NumberFormat。顯然屬于工廠模式的使用。
4)原型模式
- java.lang.Object
- protected native Object clone() 方法
- 類功能:所有類的父類
- 方法功能:根據現有實例,返回一個淺拷貝對象。
5)單例模式
- java.lang.RunTime類
- public static Runtime getRuntime()
- 類功能:每一個運行的java應用都會有一個唯一的RunTime類的實例,這個實例使得應用程序在運行期間能夠受到運行環境的影響。
- 方法功能:返回一個和當前java應用關聯的RunTime對象。
6)適配器模式
- java.util.Arrays。
- public static List asList(T… a)方法。
- 類功能:此類包含了大量對數組操作的方法。
- 方法功能:將一個引用類型的數組轉為一個List。從而可以使用List類的操作來操作數組對象,但是有一點要注意:就是不能使用add(),remove()操作,因為返回的list底層是基于數組的,數組結構是不能更改的。 list類就是這里的適配器,通過這個適配器,對數組的直接操作變為間接操作。
9.Mybatis框架中使用的設計模式有哪些?
Builder模式
- 在Mybatis環境的初始化過程中,
SqlSessionFactoryBuilder
會調用XMLConfigBuilder
讀取所有的MybatisMapConfig.xml
和所有的*Mapper.xml
文件,構建Mybatis運行的核心對象Configuration
對象,然后將該Configuration
對象作為參數構建一個SqlSessionFactory
對象。
工廠模式
-
在Mybatis中比如
SqlSessionFactory
使用的是工廠模式,該工廠沒有那么復雜的邏輯,是一個簡單工廠模式。 -
SqlSession
可以認為是一個Mybatis工作的核心的接口,通過這個接口可以執行執行SQL語句、獲取Mappers、管理事務。類似于連接MySQL的Connection
對象。
單例模式
在Mybatis中有兩個地方用到單例模式,ErrorContext
和 LogFactory
,其中 ErrorContext
是用在每個線程范圍內的單例,用于記錄該線程的執行環境錯誤信息,而 LogFactory
則是提供給整個Mybatis使用的日志工廠,用于獲得針對項目配置好的日志對象。
public class ErrorContext {private static final ThreadLocal<ErrorContext> LOCAL = new ThreadLocal<>();private ErrorContext() {}public static ErrorContext instance() {ErrorContext context = LOCAL.get();if (context == null) {context = new ErrorContext();LOCAL.set(context);}return context;}}
構造函數是private修飾,具有一個static的局部instance變量和一個獲取instance變量的方法,在獲取實例的方法中,先判斷是否為空如果是的話就先創建,然后返回構造好的對象。
只是這里有個有趣的地方是,LOCAL的靜態實例變量使用了 ThreadLocal
修飾,也就是說它屬于每個線程各自的數據,而在 instance()
方法中,先獲取本線程的該實例,如果沒有就創建該線程獨有的 ErrorContext
。
代理模式
代理模式可以認為是Mybatis的核心使用的模式,正是由于這個模式,我們只需要編寫 Mapper.java
接口,不需要實現,由Mybatis后臺幫我們完成具體SQL的執行。
適配器模式
在Mybatsi的logging包中,有一個Log接口:
該接口定義了Mybatis直接使用的日志方法,而Log接口具體由誰來實現呢?Mybatis提供了多種日志框架的實現,這些實現都匹配這個Log接口所定義的接口方法,最終實現了所有外部日志框架到Mybatis日志包的適配。
10.Spring框架中使用的設計模式有哪些?
1)簡單工廠
BeanFactory。Spring中的BeanFactory就是簡單工廠模式的體現,根據傳入一個唯一的標識來獲得Bean對象,但是否是在傳入參數后創建還是傳入參數前創建這個要根據具體情況來定。
2)工廠方法
FactoryBean接口
實現了FactoryBean接口的bean是一類叫做factory的bean。其特點是,spring會在使用getBean()調用獲得該bean時,會自動調用該bean的getObject()方法,所以返回的不是factory這個bean,而是這個bean.getOjbect()方法的返回值。
3)單例模式
Spring依賴注入Bean實例默認是單例的。
Spring的依賴注入(包括lazy-init方式)都是發生在AbstractBeanFactory的getBean里。getBean的doGetBean方法調用getSingleton進行bean的創建。
4)適配器模式
SpringMVC中的適配器HandlerAdatper。
HandlerAdatper使得Handler的擴展變得容易,只需要增加一個新的Handler和一個對應的HandlerAdapter即可。
因此Spring定義了一個適配接口,使得每一種Controller有一種對應的適配器實現類,讓適配器代替controller執行相應的方法。這樣在擴展Controller時,只需要增加一個適配器類就完成了SpringMVC的擴展了。
5)裝飾器模式
Spring中用到的包裝器模式在類名上有兩種表現:一種是類名中含有Wrapper,另一種是類名中含有Decorator。
動態地給一個對象添加一些額外的職責。
就增加功能來說,Decorator模式相比生成子類更為靈活。
6)代理模式
AOP底層,就是動態代理模式的實現。
7)觀察者模式
Spring 基于觀察者模式,實現了自身的事件機制也就是事件驅動模型,事件驅動模型通常也被理解成觀察者或者發布/訂閱模型。
8)策略模式
Spring框架的資源訪問Resource接口。該接口提供了更強的資源訪問能力,Spring 框架本身大量使用了 Resource 接口來訪問底層資源。
Rsource 接口是具體資源訪問策略的抽象,也是所有資源訪問類所實現的接口。
Resource 接口本身沒有提供訪問任何底層資源的實現邏輯,針對不同的底層資源,Spring 將會提供不同的 Resource 實現類,不同的實現類負責不同的資源訪問邏輯。