1.容易忘得設計原則
接口隔離:指接口中的功能太雜則可以拆分一下。防止實現類實現了接口后自動依賴了一些不需要的功能。不同功能拆分成不同的接口。
里氏代換:強調父類能出現的地方,子類一定能正常跑。
迪米特法則:又稱最少知識原則,只與直接朋友通信,提高模塊獨立性。
單一職責,合成復用,開閉原則
依賴倒轉: 指聚合/組合時使用抽象而非具體的子實現類。對抽象編程。降低客戶與實現模塊之間的藕合。“父類引用指向子類對象” 這說明 依賴倒轉結合使用了里氏代換原則。
2、控制反轉,指我寫了一套抽象的支付代碼,spring幫我去管理是阿里支付還是微信支付。
這個概念建立在依賴倒轉原則上。即編碼基于抽象。
依賴倒轉是說我依賴的時候不依賴具體實現了,我依賴倒轉了,變成了依賴抽象。控制反轉強調的是誰創建對象。比如由容器進行構造器注入,setter注入等。
我先依賴倒轉,依賴抽象支付工具,寫抽象代碼,然后控制反轉注入bean交給spring。這樣我的工作就大大簡化。不需要自己去太多關注支付方式。
3.關于適配器模式 與 橋接模式的聯系與區別。
適配器的典型用法: 事后補救,解決接口不兼容的問題。
class Adapter implements NewInterface {
private LegacyClass legacyObj;
適配器類實現新接口,但是組合老的實現類。通過老的實現類的方法作為input,經過一定的轉換,來返回新接口方法格式的結果。
橋接模式的典型用法:事前規劃。選取一個主維度作為主體,去組合其他的維度。
抽象層與實現分離。比如統一的UI框架與不同OS的渲染。統一的數據格式與不同的db 驅動。
或者是多維度的分離,防止類爆炸。比如形狀與顏色,車的類型與引擎的類型。
二者也經常結合使用。比如橋接模式定義一個抽象層,如數據存儲,然后組合一個Adaptor類型的實現層。
這樣在實現一個具體數據存儲的時候,可以去組合不同驅動類型的adaptor。
回過頭來,簡單總結,這個橋接模式就是用抽象組合抽象。從而減少類定義的復雜度。
4.關于單一職責原則和接口隔離原則的練習與區別。
兩者都體現了高內聚,低耦合理念。
但是單一職責強調類的職責,比如訂單類與支付類的拆分。
接口隔離原則強調接口的拆分,比如飛行功能與汽車行駛的接口功能拆分。
5.訪問者模式:
一句話總結: 不想在貓,狗類中寫關于 健康檢查,喂食等代碼。
簡單寫一個accept 方法。調用入參的Visit。
具體的健康檢查,喂食,由入參類負責。
另外一般會有一個動物園類來組合元素集合。并提供依次accept的方法。方便獸醫、喂食人員調用。
適合于你有一堆類似的元素(貓狗等),然后你又想將來以不同的方式來批量對待他們。
精髓是將操作從數據結構中分離出來,適用于操作易變,但數據結構穩定的系統。比如編譯器,UI框架。
規避場景:數據結構容易變,或者不可預知的場景。即貓狗易變,而且我也不知道啥時候集合里面會多來一種動物。
備忘錄類 典型例子是游戲存檔
存儲游戲狀態快照,但是不想讓其他人訪問,隨意修改數據。
Momento 對象,對其他人如玩家提供窄接口,僅對發起人(游戲程序員、GM、或者是數據敏感的GAMEROLE類這樣的角色等)提供寬接口。
在java中的實現方案是,將PrivateMomento 設計為 GM類的成員內部類。
GM對外提供的backup restore 都是Momento類型。實際GM進行操作時,強轉為PrivateMomento再在內部方法中偷偷操作屬性等。
精髓:針對同樣一個操作,實現雙接口。對不同類暴漏的功能數量不一樣。增強安全性。
對于無關的人,我給你一個功能很少的接口類。等到了底層真正執行的時候,你會發現它強轉了向下轉型了另外一個功能更強大的類。
7.狀態模式
把狀態抽象成類,對于同一個方法,當前是什么狀態干什么事,減少if else 的使用。
比如向前Go訂單。-> 現在是下單那就發貨,是發貨那就簽收。
8.命令模式。
用一個 含有execute的 Command 接口。來解耦請求的發起與執行。
讓請求的發起,關注命令即可,而不需要關注誰執行,如何去執行。
比如燈 implemens Command {
execute{ 燈.on }}
看了jdk 21的代碼。 Collection 接口繼承了 Iterable 接口。
public interface Collection extends Iterable
所以所有的集合類都支持迭代器。
責任鏈模式典型場景: 多層審批
實際精髓是一個很復雜的活,我只要請求一次就行了。
典型寫法 abstract class Handler{setNext(Handler)}
細分有純(經典審批),不純(如filter),動態排序的鏈(插件化架構)等。
DEBUG日志→控制臺,ERROR日志→郵件+文件。
?Web請求過濾?
Servlet Filter鏈:身份驗證→參數校驗→業務處理。
拓展知識,filter依賴Servlet規范的doFilter函數,依賴 Servlet容器,可以攔截靜態資源。
Interceptor基于動態代理實現。依賴Spring框架,僅攔截Contoller請求(springBoot2.0之前。后來的版本需要手動放行一下)。可以訪問Handler,ModelAndView等Spring上下文。
?執行流程與順序?
?Filter?:
請求 → Tomcat容器 → Filter → Servlet
多個Filter按配置順序鏈式執行(責任鏈模式)
?Interceptor?:
請求 → DispatcherServlet → Interceptor.preHandle() → Controller → Interceptor.postHandle() → 視圖渲染 → Interceptor.afterCompletion()
支持更細粒度的生命周期控制(如preHandle返回false可中斷請求)。
請求先經過Filter才進入DispatcherServlet。
所以先Fileter后intercepter。
掌握兩者生命周期差異(Filter在Servlet前后,Interceptor在Controller前后),并強調Interceptor與Spring的協同優勢(如Bean注入、路徑精確控制)。實際項目中常組合使用,例如Filter處理全局安全,Interceptor處理業務權限。
模板方法:
父類定義算法骨架,并允許子類重寫特定步驟。在源碼中應用廣泛。
AbstractApplicationContext類中的finishBeanFactoryInitialzation方法調用了子類的getBean方法。因為getBean的實現與環境息息相關。具體的實現類有classPathXMLApplicationContext的基于XML配置的。或者基于配置類+注解方式的AnnotationConfigWebApplicationContext。
抽象類InputStream類中定義了read方法。
需要子類去實現。但是read前后還有一些其他邏輯,子類就不需要去關注了。比如讀多少字節,什么時候停止。子類只要保證能正確讀取一個字節即可。
HttpServlet中的 doGet doPost交給子類實現。子類專注于業務細節。
HttpServlet比較老的概念,原生Servlet開發痛點是每個Servlet需要獨立配置web.xml路由映射。
而SpringMVC 通過@requestMapping注解替代配置。
?底層依賴關系?:
Controller 的調用依賴 DispatcherServlet(HttpServlet 的子類),但 Controller ?并非 Servlet 的直接實現?。
Controller 是 Spring MVC 對 Servlet 的高層抽象,通過注解和框架機制簡化開發,提升可維護性。讓程序員專注于業務細節,忽略協議處理。
12。常見應用場景:spring Spel源碼, jdk正則, mybitis sql解析引擎。缺點是太負責的語法在性能上難以支撐。其價值在于為特定領域語言提供輕量級解析方法。
將運算、變量都定義為對象
將表達式解析為 表達式 運算符 表達式。遞歸的去運算,直到能算出結果,簡單的使用了遞歸。性能比較差。
13.手寫策略模式
要記得有個環境類。聚合了策略。
可以set策略,執行策略。
表達時,可以說字節切換推薦策略,比如按熱度,時間,相關性。
加分項:配置中心,熱更新。
工廠模式+配置文件解決策略類過多的問題。
缺點是客戶端要了解策略。
java關鍵字都是小寫
public interface SortingStrategy{
void sort (int data);
}
BubbleSort
@Override
QuickSort
@Override
SortContext
setStrategy
executeSort
public class StrategyDemo
public class StrategyDemo {
public static void main(String[] args) {
int[] data = {5, 2, 9, 1, 5};
SortContext context = new SortContext();// 動態切換策略context.setStrategy(new BubbleSort());context.executeSort(data); // 輸出:使用冒泡排序context.setStrategy(new QuickSort());context.executeSort(data); // 輸出:使用快速排序
}
}