2022年2月28日 星期一

Dropdown優秀的寫法


@Autowired
    private PatientExamineRepo patientExamineRepo;

    @Override
    public List findAllByStatusTrue() {
        return patientExamineRepo.findAllByStatus(true).stream().map(p -> {
            PatientExamineVo vo = new PatientExamineVo();
            vo.setId(p.getId());
            vo.setExamName(p.getExamName());
            return vo;
        }).collect(Collectors.toList());
    }

覺得這裡的寫法蠻優秀的

簡單的撈出, 然後用stream的map替換掉內容再直接返回Collect的list

但是, 其中stream和List我認為就clean code概念應該分行完成

應該先撈出list再做stream map

2022年2月23日 星期三

java pdf table 垂直順序, 分兩列 vertical order in horizontal split table

 我使用的套件是openpdf, 是取代itext低版本套件問題的解決方案其一





而~其中的cell都是一列一列, 從左至右增加

所以, 當資料要按垂直順序, 又要分兩側平均的時候

這就是本篇的難點

如下圖, 長相要向下排, 左邊排完再換右邊

但是程式上, 基本上只能一行一行資料出來的時候








我一開始的出發點是, 其實把資料除以二

左側和右側, 數字差距一半

但是偶數會整除, 奇數會多一

於是乎~當奇數列時, 列會多一列, 但是最後一行只要印出左側, 資料就印完








程式碼如上~資料分兩列, 完成!

2022年2月1日 星期二

[Geroge]設計模式-策略模式Strategy Pattern

策略模式定義了一系列的算法, 並將每一個算法封裝起來, 而且使他們還可以相互替換, 策略模式讓算法獨立於使用它的客戶而獨立變化

解決問題:

讓算法和對向分開, 使得算法可以獨立於使用它的客戶而變化

當存在以下情況使用Strategy模式

1 許多相關的類僅僅是行為有異, "策略"提供了一種用多個行為中的一個行為來配置一個類的方法, 即一個系統需要動態地在幾種算法中選擇一種

2 需要使用一個算法不同的實體, 例如, 你可能會定義一些反應不同空間/時間權衡的算法, 當這些變體實現為一個算法的類層次時, 可以使用策略模式

3 算法使用客戶不應該知道的數據, 可使用策略模式以避免暴露複雜的, 與算法相關的數據結構

4 一個類定義了多種行為, 並且這些行為在這個類的操作中以多個條件語句的形式出現, 將相關的條件分支移入它們各自的Strategy類中以代替這些條件語句






環境類(Context): 用一個ConcreteStrategy對象來配置, 維護一個對Strategy對象的引用, 可定義一個介面來讓策略類訪問它的數據

抽象策略類(Strategy): 定義所有支持的算法的公共介面, Context使用這個介面來調用某具體Strategy的定義算法

具體策略類(Concrete Strategy): 以Strategy介面實現某具體算法

例子:

我們有一個人要去旅行, 我們定義抽象介面旅行












這時, 旅行可以用不同種策略達到, 可以用走的, 搭火車的, 搭飛機的













這時候, 我們使用不同的策略, 只需要抽換介面的實現類, 在構造函數中傳入就可以運行了, 每當增加新的策略時, 不用改變Person和Travel中的任何程式碼








優點:

1 相關算法系列Strategy類層次為Context定義了一系列可供重用的算法或行為, 繼承有助於析取出這些算法中的公共功能

2 將算法封裝在獨立的Strategy類中使得你可以獨立於其Context改變它, 使它易於切換, 易於理解, 易於擴展

3 消除了一些if else 條件語句: Strategy模式提供了用條件語句選擇所需的行為以外的另一種選擇, 當不同行為堆砌在一個類中時, 很難避免使用條件語句來選擇合適行為, 將行為封裝在一個個獨立的Strategy類中消除了這些條件語句, 含有許多條件語句的程式碼, 通常意味著需要使用Strategy模式

4 實現的選擇Strategy模式可以提供相同行為的不同實現, 客戶可以根據不同時間/空間權衡取捨要求從不同策略中進行選擇


缺點:

1 客戶端必須知道所有的策略類, 並自行決定使用哪一個策略類, 可以結合工廠模式來克服這個問題

2 增加Strategy和Context之間的通信開銷, Strategy和Context之間進行更緊密的耦合

3 策略模式將造成產生很多策略類

https://www.youtube.com/watch?v=cA-vt0Nf1nQ&list=PLGmd9-PCMLhb16ZxeSy00qUsBazXgJyfM&index=21

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

[Geroge]設計模式-觀察者模式Observer Pattern (下)

推模式

被觀察者對象向觀察者推送主題的詳細信息, 不管觀察者是否需要, 推送的信息通常是主題對象的全部或部分數據, 一般這種模型的現實中, 會把被觀察者對象中的全部或部分信息通過update的參數傳遞給觀察者 update(Object obj)

拉模式

被觀察者在通知觀察者的時候, 只傳遞少量信息, 如果觀察者需要更具體的信息, 由觀察者主動到被觀察者對象中獲取, 相當於是觀察者從被觀察者中拉數據

一般這種模型的實現中, 會把被觀察者對象自身通過update方法傳遞給觀察者update(Subject subject)這樣在觀察者需要獲取數據的時候, 就可以通過這個引用來獲取了

例子:

推模式

就是會推送信息, 我們就先造出信息類Weather, 用來放溫度和濕度











觀察者抽象類, update時傳送信息Weather物件






而subject實體類, 就是氣象站, 這裡當溫度或濕度改變的時候
我們必須產生Weather物件當作信息, 推送給觀察者








推送, 就是向已經註冊在列表中的觀察者, 去進行update並把Weather信息傳過去










觀察者物件被調用update時, 就會依照傳過來的Weather進行反應











這是整體進行的程式碼, 過程中看不到Weather物件, 是因為設置傳送Weather物件都在內部進行
















拉模式
相當於說觀察者更新的時候, 是傳送real subject過去, 就是傳氣象站過去




老王和小李則是獲得Weather Station對向作判斷















那我們Weather Station也會發生變化, 就是推送它自己了, 而不是Weather物件











當它改變溫度或濕度的時候, 我們只要調用notifyObserver()






重述一下拉模式重點

首先, 我們的Subject中的notifyObserver就不用傳訊息物件過去

另外我們的Observer類別需要傳Subject實體類過去















兩種模式的對比

推模式

優點: 很好保護了subject 降低觀察者與具體subject的耦合度

缺點: 當變化的參數繁多的時候, 觀察者將收到大量無關信息

拉模式

優點: 變化時對觀察者根據需要去取相應數據

缺點: 觀察者與具體subject的耦合度大大增加

https://www.youtube.com/watch?v=cA-vt0Nf1nQ&list=PLGmd9-PCMLhb16ZxeSy00qUsBazXgJyfM&index=20

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


[Geroge]設計模式-觀察者模式Observer Pattern (上)

觀察者模式 Observer Pattern

有時候又被稱為 Publish-Subscribe模式(發布訂閱), 模型-視圖(View)模式, 源-收聽者(Listener)模式或從屬者模式, 是軟體設計模式的非常常見一種, 定義對象間的一種一對多的依賴關係,當一個對象的狀態發生改變時, 所有依賴於它的對象都得到通知並被自動更新, 此種模式通常被用來實現事件處理系統







抽象主題角色(subject): 把所有對觀察者對象的飲用保存在一個集合中, 每個抽象主題角色都可以有任意數量的觀察者, 抽象主題提供一個介面, 可以增加和刪除觀察者角色, 一般用一個抽象類和介面來實現

抽象觀察者角色(observer): 為所有具體的觀察者定義一個介面, 在得到主題的通知時更新自己

具體主題角色(concrete subject): 在具體主題內部狀態改變時, 給所有登記過的觀察者發出通知, 具體主題角色通常使用一個子類實現

具體觀察者角色(concrete observer): 該角色實現抽象觀察者角色所要求的更新接口,以便使本身狀態與主題的狀態相協調, 通常用一個子類實現, 如果需要, 具體觀察者角色可以保存一個指向具體主題角色的引用

觀察者模式解決的問題

觀察者模式作為一種設計模式, 就是一種解決問題的方案, 也可以講是一個模板, 方法, 目的就是已通知代替輪詢: 當被觀察者狀態發生改變時, 會觸發觀察者發生改變

解耦觀察者與被觀察者的實現, 觀察者和被觀察對象之間的互動關係不能體現成類之間的直接調用, 否則就將使觀察者和被觀察對象之間緊密的耦合起來, 從根本上違反面向對象的設計原則, 無論是觀察者觀察對象, 還是被觀察者將自己的改變通知觀察者, 都不應該直接調用

例子:

首先先造 觀察者 和 主題角色 的抽象類

觀察者, 會依照觀察狀態而改變

主題角色, 會註冊觀察者, 移除觀察者, 通知觀察者








然後我們在具體主題角色(氣象站)中

有觀察者列表, 其中有註冊觀察者, 移除觀察者和通知觀察者

也有觀察變量, 溫度及濕度, 在變量改變的時候調用通知觀察者

而通知觀察者裡面的方法, 是將註冊在列表中的觀察者一一進行更新的調用














那我們需要觀察者的具體對象, 對變量改變的時候進行反應
















然後運行, 我們先New 出氣象站, 老王, 小李

然後將老王和小李註冊到氣象站中

當溫度或濕度變化的時候, 讓氣象站主動去通知老王和小李






讓氣象站通知老王跟小李就是下面這段程式碼作用











詳細運作, 假設當溫度改變的時候

進行邏輯為: 

氣象站設置溫度>

將註冊列表中的對象更新>

更新中對持有的氣象站進行變量判斷, 若是濕度超過則繼續進行邏輯

https://www.youtube.com/watch?v=cA-vt0Nf1nQ&list=PLGmd9-PCMLhb16ZxeSy00qUsBazXgJyfM&index=19

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

[leetcode] [KMP] KMP

ABCDABD... ABCDABF... 簡單的說, 傳統解兩字串匹配部分 可能會來個雙迴圈, 哀個比對, 當不匹配的時候, 會將下方列再後移1位 然後不匹配再後移 然而 如果像上放已經有4個屬於匹配的字串, 她就應該直接往後移四位來匹配, 而不是只移動1位 隱藏的思維是, 當...