2022年1月11日 星期二

[Geroge]面向對象設計-介面隔離原則ISP

 --影片內容--

介面隔離原則(Interface Segregation Principle)

定義: 使用多個專一的介面, 總比一個總介面好

高內聚

優點: 會使一個軟體系統功能擴展時, 修改的壓力不會傳到其他對象那裏


例子:

我們有一個星探類Search, 他要來找尋明演員, 一個好的女演員需要好看good looking, 好身材good figure, 還有好的脾氣temper, 我們就用IPrettyGirl做為這些抽象標準的介面, Search 只要找到IPrettyGirl就行, 而Angelababy剛好實行這個介面, 具有三種能力, 如下圖







然而, 今天變更需求, 有另外一個星探, 他只需要女生有 好身材 good figure就可以了, 那他和IPrettyGirl使用相同介面就不合適, 因為他只需要其中的niceFire功能, 因此就調整如下








我們將INiceFigure抽離出來成另一個介面, 本來的IPrettyGirl改名IGoodGirl, 然後生出一個抽象類 BasePrettyGirl 去實行INiceFigure和IGoodGirl這兩個介面, 因此AngelaBaby作為子類去繼承BasePrettyGirl , 此時SearchB 最小需求~想要有好身材的女生, 就能滿足, 也就是要使用到更多功能的可以去依賴BasePrettyGirl 介面, 而只要看好身材只需要依賴INiceFigure介面, 這樣就達到很好的擴展





















































感想, 這樣做的好處, 對於SearchB來說, AngelaBaby更多的細節就隱藏起來, 他只需要知道她是不是implement Nice Figure就好

參考: 

https://www.youtube.com/watch?v=W7b7zcxUxr8&list=PLGmd9-PCMLhb16ZxeSy00qUsBazXgJyfM&index=8

https://github.com/iw5420/geroge-design-pattern

2022年1月10日 星期一

[Geroge]面向對象設計-依賴倒置原則DIP

 --影片內容--

依賴導致原則(Dependency Inversion Principle)

定義: 要依賴抽象, 不要依賴於具體, 客戶端依賴於抽象耦合

低耦合

抽象不應當依賴於細節, 細節應當依賴於抽象

要針對介面編程, 不針對實現編程

優點: 使用傳統過程化程序設計所創建的依賴關係, 策略依賴於細節, 這是糟糕的, 因為策略受到細節改變的影響, 依賴導致原則使細節和策略都依賴於抽象, 抽象的穩定性決定了系統的穩定性


例子:

一個mother類別, 具有讀書功能, 如果我們將它和Book類別綁在一起, 很顯然, 如果mother要讀Newspaper就沒有辦法實行, 這就是依賴具體, 改法是, 產生一個抽象的介面, 使Mother類別去依賴抽象的介面























這樣設計下, 就使Mother讀取內容變得很有彈性, 可以是Book, 可以是Newespaper, 依賴介面設計, 依賴抽象, 而不是依賴於具體的實現, 這樣我們程式的靈活性就更好了

參考: 

https://www.youtube.com/watch?v=f4u4YNhCO6U&list=PLGmd9-PCMLhb16ZxeSy00qUsBazXgJyfM&index=7

https://github.com/iw5420/geroge-design-pattern



[Geroge]面向對象設計-里式替換原則LSP

--影片內容--

里式替換原則(Liskov substitution Principle)

定義: 子類型必須能夠替換它們的基類型, 一個實體如果使用是一個基類, 那麼把這個基類替換成繼承該基類的子類, 程序的行為不會發生任何變化, 實體察覺不出基類對象和子類對象的區別

低耦合

優點: 可以很容易的實現同一父類下各個子類的互換, 而客戶端可以毫不察覺

---------------------------------------------

感覺影片的理論部分少了點

下面補充一下他網的資源

----------------------------------------------

關於背景:

1 當初由Liskov 女士提出, 下面這段話

繼承必須確保父類所擁有的性質在子類中仍然成立(Inheritance should ensure that any property proved about supertype objects also holds for subtype objects)。

2 里式替換原則- 講述繼承的原則, 也就是什麼時候應該要用繼承, 也可以視為對開閉原則的補充, 為實現抽象化步驟的規範


關於作用:

1 實現開閉原則重要方法之一

2 克服了重寫父類造成可複用性變差的缺點

3 為動作正確性的保證, 新的類擴展, 不會給已有的系統帶來錯誤, 降低程式碼出錯機會

4 加強程式碼的穩健性, 同時變更時可以做到優良的兼容性, 提高程式可維護, 擴展性, 降低需求變更帶來的風險


關於定義

1 子類可以實現父類抽象方法, 但是不可以覆蓋父類非抽象方法

2 子類可以增加自己特有方法

3 子類方法重載父類的方法時, 前置條件要比父類方法更寬鬆

4 子類實現父類方法時, 方法後置條件要比父類方法更嚴格或相等

-----

範例

我們有一個父類Gun類別, 另外有兩個子類HandGun, Rifle去繼承它, 並有一個Soldier依賴Gun去完成殺敵的行為



















我們現在要新增一個ToyGun去繼承Gun, 然而我們發現, 它這裡發生了嚴重的邏輯錯誤, 因為ToyGun是不能殺敵的, 所以它在Soldier執行射擊之後, 完成殺敵的行為, 明顯有邏輯的錯誤, 這就是因為它違反了里式替換原則, 子類並不能完全替換父類功能











這時候我們必須重新來設計, 我們需要新加一個Weapon類

讓所有可攻擊的武器去繼承



而玩具槍去繼承Gun類別, 沒有射擊功能





類別圖如下







小心得

符合里式替換原則的程式, 的確有其穩健性, 避免程式邏輯錯誤

參考: 

https://www.youtube.com/watch?v=DWkggQoxFeI&list=PLGmd9-PCMLhb16ZxeSy00qUsBazXgJyfM&index=6

https://github.com/iw5420/geroge-design-pattern

2022年1月8日 星期六

[Geroge]面向對象設計-開放封閉原則OCP

開放封閉原則(Open-Closed Principle)

定義: 對擴展開放, 對修改關閉, 軟體實體盡量在不修改原有程式碼的情況下進行擴展

高內聚, 低耦合

優點: 降低了程式各部分之間的耦合性, 為了滿足開閉原則, 需要對系統進行抽象化設計, 抽象化是開閉原則的關鍵

其適應性, 靈活性, 穩定性都比較好, 當已有軟體系統需要增加新的功能時, 不需要對作為系統基礎的抽象層進行修改, 只需要在原有基礎上附加新的模塊就能實現所需要添加的功能, 增加的新模塊對原有的模塊完全沒有影響, 或影響很小, 這樣就無需為原有模塊進行重新測試

範例: 我們有pie bar line三個圖形的類別, 並有一個ChartDisplayManager類別, 目前當有新增新的圖要顯示, 就必須做兩個地方修改, 1 新增一個類 2對原有的ChartDisplayManager進行修改

而2的部分就違反了封閉原則, 他每次新增都修改了原程式碼















那修改方式這樣, 我們要將原有的chart抽象, 新增一個父類BaseChart




那我們所有的chart都來繼承這個父類







然後我們的ChartManager都調用這個BaseChart















這時, 當我們需要新增一個圖表, 我們只需要新增一個類別去繼承chart類別

而對ChartDisplayManager就不用修改, 意即對修改封閉


參考: 

https://www.youtube.com/watch?v=RVddmAln3OU&list=PLGmd9-PCMLhb16ZxeSy00qUsBazXgJyfM&index=5

https://github.com/iw5420/geroge-design-pattern


2022年1月5日 星期三

itext AGPL 問題 及 改套件 openpdf

處理dependency check 的問題接近尾聲, 大致上能改的只剩下itext




上面是有發生問題的套件
而~itext 在五版5.5.12才有解決這方面問題




然而itext從5以後都是follow AGPL的協定

AGPL意思是~我的東西全部是開放的, 可使用, 但是不可修改


但是我使用AGPL, 你要使用我的東西, 你也要AGPL

因此商業用途下, 你要碼就跟著我一起開放原始碼

不然~請乖乖付給我business license的費用

如下>我是AGPL, 你要使用, 請在同樣AGPL條件下使用






如下>你如果不想開放原始碼, 請付錢





還好~由於是同一個開發者緣故

他有另外開源一套openpdf提供給大家使用

目前~是還沒有聽說要收費

所以itext還是可以無痛換openodf

原本dependency







修改後dependency





程式碼的部分目前只要改三部分

1 引入套件部分由 com.lowagie. 修改成 com.itextpdf.











2 引入 import com.itextpdf.awt.AsianFontMapper; 改成引入 com.lowagie.text.pdf.AsianFontMapper;

3使用BaseColor類別的部分, 由 RGBColor類別替換


經過這三個步驟, 基本上PDF產出, 是完全順利, 連中文也可以

只是中文部分程式碼會需要這樣寫

BaseFont baseFont = BaseFont.createFont(AsianFontMapper.ChineseTraditionalFont_MHei, AsianFontMapper.ChineseTraditionalEncoding_H, false);

Font mainTitleFont = new Font(baseFont, 16, Font.BOLD, RGBColor.BLACK);

table.addCell(this.genCell("血液透析紀錄表", mainTitleFont, Element.ALIGN_CENTER, 1, 3));


這樣就大功告成~finished!




參考: 

https://itextpdf.com/en/how-buy/agpl-license

https://snyk.io/vuln/maven:com.itextpdf%3Aitextpdf




2022年1月3日 星期一

jackson-mapper-asl-1.9.13.jar dependency check CRITICAL 解決方式

因為他是指出專案中的jackson問題

所以~我回去找dependency看看哪邊用到






可以發現左下角 spring-security-oauth2-autoconfigure 使用的2.2.13 release版本

使用到這個有資安問題的jar包

我嘗試性做升級到目前最新的版本如下







為2.6.1版本

當我升級過後




可以發現原本使用到有資安問題的jar檔

已經沒有在使用


*很多在更新版本的時候, 已經將有資安問題的引用改掉

*因此, 在學習新技術的時候, 還是盡量能以最新版好點

面向對象設計-單一職責原則SRP

 面向對象設計 目標

1 可擴展性 - 新功能易新增

2 靈活性 - 新增過程中, 不因舊功能僵固而進行困難

(不會改功能A 導致功能B無法使用)

3 可插入性 - 容易把一個類別抽出去, 替換相同介面的類進來使用


判斷軟體設計質量的標準

高內聚, 低耦合


*耦合性: 模塊與模塊, 類與類之間相互聯繫的緊密程度->獨立性弱->如果一個類不存在, 另外一個類就無法運作

*內聚性: 模塊內部, 或是 類內部的元素, 程式區塊, 關聯越緊密, 內聚性越高


*高內聚:軟體模塊由相關性很強的程式碼組成, 只負責一項任務, 不可分割

*低耦合:模塊之間, 類與類之間, 盡可能的獨立存在, 以最低程度的關聯進行協作

------------------------------------------------------------------------

單一職責原則 (Singke-Responsibility Principle)

定義: 一個類只負責一個功能領域中的相應職責, 或可以定義為: 就一個類而言, 應該只有一個引起它變化的原因

高內聚

一個類承擔的責任越多, 它可被復用的可能性就越小, 而且一個類承擔的責任過多, 就相當於將這些職責偶合在一起, 當其中一個職責變化時, 可能會影響到其他職責的運作, 因此要將這些職責進行分離,將不同的職責封裝在不同的類中, 即將不同的變化原因封裝在不同的類中, 如果多個職責總是同時發生變化則可將它們封裝在同一個類中

好處:

1 可降低類的複雜度, 一個類只負責一向職責, 其邏輯肯定比負責多項職責簡單的多

2 複雜度低, 可讀性自然提高

3 可維護性高, 風險低, 如果介面的單一職責好, 一個介面修改指對應相應的實現類有影響, 對其它的介面無影響, 這對系統的擴展性, 維護性都有很大的幫助

範例: 原本CustomerChart類別中包含兩個功能

一個是查找數據庫, 另一個是顯示列表










然而我們今天查找數據庫發生變化, 原本使用mysql改成用mogodb

這樣, 這一個類, 它就不存在了, 它需要進行修改

CustomerChart本身關心顯示列表, 並不關心查找數據庫, 我們可以將這功能撥離

產生一個CutomerDao用來查找數據庫
















這樣我們未來設計, 如果改變數據庫, 我們只要在這裡new一個CustomerDao

而CustomerChart本身並不需要進行任何改變, 我們就使CusomerChart實現了單一職責原則

就是他只管它該管的事情, 而不管它不該管的事情

參考: 

https://www.youtube.com/watch?v=oKu6q6Nnvdk&list=PLGmd9-PCMLhb16ZxeSy00qUsBazXgJyfM&index=4

https://github.com/iw5420/geroge-design-pattern




量身訂做建議(37 歲,6 年 Java 後端工程師)from chatgpt

🎯 量身訂做建議(37 歲,6 年 Java 後端工程師) 1️⃣ 先看你的條件 年齡 37 屬於「中高年資」工程師,履歷上的 深度 / 系統設計能力 會比「語言多寡」更重要。 6 年 Java 後端 代表你在 Spring Boot、資料庫、API 設計...