2022年1月10日 星期一

[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




2021年12月27日 星期一

多益線上家教 收費300元 版本202112

 *具有多年讀書會經驗

*聽力穩定450分以上(490分2次)

*懂得如何從低分群準備到高分群

*多次考試經驗, 並從準備考試中建構會話基礎 主教多益聽力部分,以及準備方法 每周上課1小時,會出一天份量的回家作業 藉由每周進度,幫助久未接觸英文的工作人 找回英文的熟悉度,並累積英文基礎能力 養成良好的學習模式 本次學生程度為400-600 目前人數:4~6 地點:Teams 線上 時間:周日 晚上8:30 - 10:00 收費:300 聯絡方式 : 站內私訊,或是line: iw5420 教材:由老師提供,也可自行購買課本

補充 : 程度較好的同學如要拚600-800分以上,
可以白天另外約時間分享準備方式,
藉由進行一段時間的家教陪讀,
程度達成一定的提升

2021年12月19日 星期日

[Spring Boot] Cookie Without Secure Flag

目前情況如下圖






我們可以看到endpoint api的Cookie, 它的HttpOnly和Secure是空白的

根據下面這一篇
https://stackoverflow.com/questions/34489406/adding-httponly-and-secure-flag-for-set-cookie-in-java-web-application










我們可以得知, sesson-config中可以設置安全cookie相關項目
因此, 推測在appication.properties檔案應該有相對應的配置
在看過下面這一篇
https://stackoverflow.com/questions/40974955/spring-boot-java-config-set-session-timeout
得知有server,servlet.session項目, 因此推測在他之下可能能設置cookie
很幸運的回去appication.properties檔案嘗試, 的確有cookie的設置





設置完的結果發現, JSESSIONID 的cookie secure設置確有改變, 如下圖







可是其他的cookie都沒有改變, 怎麼辦呢?
剛好我有查到這一篇
https://rules.sonarsource.com/java/tag/owasp/RSPEC-2092





可以發現在new出來Cookie的時候, 再setSecue就可以了

解決方式->在專案全局中搜尋Cookie字樣, 將其設置secure再回傳
範例

1產生一個處理類

@Component
public class CookieSecureUtils {
	public static Cookie setSecure(Cookie targetCookie) {
		targetCookie.setHttpOnly(true);
		targetCookie.setSecure(true);
		return targetCookie;
	}
}

2載入類


	@Autowired 
	private CookieSecureUtils cookieSecureUtils;

2送出cookie前,設置安全


	response.addCookie(cookieSecureUtils.setSecure(new Cookie("domain", resultObj.getString("domain"))));
	response.addCookie(cookieSecureUtils.setSecure(new Cookie("account", account)));
	response.addCookie(cookieSecureUtils.setSecure(new Cookie("lang", request.getParameter("lang"))));
成果如下圖



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

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