文章目錄
- 引言
- 正文
- 依賴倒轉原則
- 工廠方法模式
- 工廠模式的實現
- 簡單工廠和工廠方法的對比
- 抽線工廠模式
- 最基本的數據訪問程序
- 使用工廠模式實現數據庫的訪問
- 使用抽象工廠模式的數據訪問程序
- 抽象工廠模式的優點和缺點
- 使用反射+抽象工廠的數據訪問程序
- 使用反射+配置文件實現數據訪問程序
- 單例模式
- 單例模式
- 多線程時的單例
- 雙重鎖定
- 靜態初始化方法
- 面試八股
- 總結
引言
- 躊躇了差不多半天吧,上午寫算法一直到一點半,然后的簡單做了個飯 ,吃了個飯,兩點半了,然后睡了一覺。起來三點鐘了,背了二十分鐘書,出去拿快遞,現在已經四點鐘了,才開始一天的工作的,后續還有兩件大事,不行,得加快進度。
- 每天哪里在浪費時間呀,早上應該直接把衣服丟到洗衣機里面,然后開始背書,書背完了,直接就能去晾衣服了,然后刷算法那,然后開始補充自己的基礎知識。
- 明天再快點好嘛!加油,兄弟,不然照這個進度下去,鐵定是要完蛋的。
正文
依賴倒轉原則
- 原話:抽象不應該依賴細節,細節應該依賴于抽象的
- 針對接口編程,不要堆實現編程
- 高層模塊不應該依賴低層模塊,兩個都應該依賴抽象
補充—— 里氏代換原則
- 子類必須能夠替換掉他們的父類型
- 只有當子類可以替換掉父類,軟件單位的功能不受到影響時,父類才能真正的被復用,而子類也可以在父類的基礎上增加新的行為
- 由于子類型的可替換性,才使得父類類型的模塊在無需修改的情況下,就可以擴展
本質
- 依賴倒轉是面向對象設計的標志,編寫程序時考慮的是如何針對抽象編程,而不是針對細節編程。
- 程序中所有的依賴關系都終止于抽象類或者接口,這就是面向對象設計。
工廠方法模式
對比簡單工廠的實例
- 簡單工廠類接受一個標記或者說字符串,然后給出創建好的實例對象,實現對應的功能。
工廠模式的實現
- 下述是工廠類實現的UML圖,感覺比較難懂,沒看懂
- 對應實現代碼
- 加減乘除各建一個具體工廠去實現接口,這些不同運算符的工廠是依賴于具體運算對象
- 客戶端實現的方式,通過創建一個加法工廠,然后通過加法工廠,獲取對應加法操作對象實例,進行對應操作
簡單工廠和工廠方法的對比
簡單工廠
- 簡單工廠模式的最大優點在于工廠類中包含了必要的邏輯判斷,根據客戶端的選擇條件動態實例化相關的類,對于客戶端來說,去除了與具體產品的依賴。
- 如果要對簡單工廠類的相關功能進行擴展,除了需要增加相關的操作類,還需要修改工廠類的邏輯
- 違背了:修改封閉的原則,雖然遵循了開放擴展的原則。
工廠模式
- 定義一個用于創建對象的接口,讓子類決定實例化哪一個類
- 工廠方法使一個類的實例化延遲到其子類
- 在上面的代碼中,這個product就是一個operation對象,然后具體對應到功能,就是返回一個對應的operation子類的對象
- 根據依賴倒轉原則
- 把工廠類抽象出一個接口,這個接口只有一個方法,就是創建抽象產品的工廠方法
- 所有要生產具體類的工廠,都去實現這個接口。
- 如果要擴展新的功能,就只需要繼承并實現對應的工廠抽象類
將簡單工廠模式的工廠類,變成一個工廠抽象接口和多個具體生成對象的工廠,擴展只需要的增加方法類和具體工廠類即可
特點:
- 工廠模式將簡單工廠的內部邏輯判斷,移到了客戶端代碼來進行
總結
- 工廠方法克服了簡單工廠違背開放-封閉原則的缺點,保持了封裝對象創建過程的優點
- 但是并不是最佳,還需要修改客戶端的代碼,通過反射可以進一步修改
抽線工廠模式
最基本的數據訪問程序
- 上述程序的問題
- SqlServer這個具體的數據庫對象和用戶端高度綁定,如果更換數據庫為access,需要修改大量內容,包括客戶端的代碼已經對應的get方法和insert方法
使用工廠模式實現數據庫的訪問
- 這里為了降低耦合度,將數據庫訪問方式和用戶端開發進行分離,所以使用工廠方法實現
- 上述是定義了user訪問的接口,然后針對不同的數據庫定義不同的接口訪問類
- 上述是具體的產品類,然后定義相關產品的具體工廠對象
- 客戶端只需要根據要求創建對應具體工廠實現類即可。
- 通過上述方式實現業務邏輯和數據訪問的解耦,IUser對象就不需要具體知道是什么實現了數據庫訪問,但是能夠很好地完成工作。
使用抽象工廠模式的數據訪問程序
- 提供一個創建一系列相關或者相互依賴對象的接口,而無需執行他們具體的類(比起工廠方法,抽象工廠就是涉及到多個product類)
- 針對上述方法抽象工廠模式,用戶端在具體使用的時候,創建具體產品類的工廠的concreteFactory,然后通過該具體工廠對象獲取對應的產品類productB1和productA1等,實現具體的功能
抽象工廠模式的優點和缺點
-
易于交換產品系列:
- 一個具體的工廠類只需要在初始化的時候出現一次就行,改變一個應用具體的實現類(使用不同的數據庫)十分容易,只需要改變具體的工廠就行。
- 既然不能防止需求改變,那就想方設法讓需求改變帶來的改動最小。
-
讓具體的創建實例過程和客戶端分離
- 客戶端通過抽象接口操作實例,產品的具體類名也被具體的工廠實現分離,不會出現在再客戶端你代碼中
缺點
- 新增加一個表,需要改的代碼太多了,抽象的工廠類以及每一個具體的類,還有對應表格映射類
- 始終無法做到只修改一行語句,就實現替換對應的工廠類
- 上述客戶端代碼中如果調用了100次new SqlFactory,那么你每一次修改對應的數據庫,都要修改一百次這樣的語句。
使用反射+抽象工廠的數據訪問程序
- 依賴注入(Dependency Injection)和IoC容器管理
反射就是使用字符串變量替換了原來的生成對象的語句,所以以后一旦要修改使用的具體產品工廠,只需要修改這個字符串變量,不需要寫對應生成對象的語句,而通過設置配置文件或者全局變量,能夠實現只改變一個變量值,替換所有的數據庫
- 上述是兩種不同的創建工廠的方式,一種是常規方式,另外一種是使用了反射機制,通過字符串變量名來加載對應的工廠實例
- 修改為對應oracle數據訪問,就只需要修改對應的變量就行了
使用反射+配置文件實現數據訪問程序
- 在簡單工廠中使用反射機制來去除switch和if等條件分支語句,降低程序的耦合度。
單例模式
- 將類的構造方法聲明為private,讓外界無法訪問他,也就沒有辦法構造對應的實例,再寫一個共有的方法,調用私有的構造方法,在公有的方法中對類是否存在進行判定。
單例模式
- 保證一個類僅有一個實例,并提供一個訪問它的全局訪問點
- 主要是讓類自身負責保護他的唯一實例,這個類可以保證沒有其他實例可以被創建
- 提供一個訪問該實例的方法
- 客戶端代碼
好處 - 保證唯一的實例
- 單例模式封裝他唯一的實例,可以嚴格控制客戶怎么樣訪問它以及何時訪問它
- 對唯一實例的受控訪問
多線程時的單例
- 多個線程同時訪問單例時,會創建多個實例,需要加鎖控制
- 因為會有多個線程同時通過判定語句,創建多個實例對象,因為對象不一定存在,所以要額外創建一個實例對象鎖。
- 上述方法有問題,就是每一訪問,都需要經歷一次鎖,降低了并發度,影響了性能。
雙重鎖定
- 使用這種方法只有實例不存在的時候,才會進行加鎖判定。
靜態初始化方法
-
在類 加載的過程中,就創建了對應的實例,不用再調用的才創建實例
-
餓漢式單例類
- 只有類在被加載的時候,才會將自己實例化,一開始創建的時候就實例化,不需要調用才實例化
- 靜態初始化方法,隨著類的加載而創建實例,提前占用系統資源,
-
懶漢式單例類
- 要在第一次被引用的時候,才會將自己實例化。
- 不會提前占用系統資源
面試八股
說一說簡單工廠模式
工廠方法模式了解嗎
抽象工廠模式了解嗎
什么是單例模式?單例模式的特點是什么?
單例模式的常見寫法有哪些
總結
- 簡單工廠模式和工廠模式看了一下,發現確實能夠降低代碼開發耦合度,以前打比賽的時候,就應該使用這種方法進行開發,不然每一次都需要的給隊友好好講一下代碼的邏輯,他要什么,我再給他一個創建一個對象或者接口,最后代碼差不多有三千多行,沒有意義。
- 今天終于看完了單例模式和工廠模式以及抽象工廠模式,想想當初面試騰訊的時候,我真的是再胡扯蛋,連基本的單例模式都不知道。真的是無語。過不了也是正常地,有沒有項目,然后最基本的一些知識點也過不了,難怪哈。
- 題目大概就截了圖,明天早上趕早,背一下題目。