日本黄色一级经典视频|伊人久久精品视频|亚洲黄色色周成人视频九九九|av免费网址黄色小短片|黄色Av无码亚洲成年人|亚洲1区2区3区无码|真人黄片免费观看|无码一级小说欧美日免费三级|日韩中文字幕91在线看|精品久久久无码中文字幕边打电话

當前位置:首頁 > 單片機 > 架構師社區(qū)
[導讀]??我將常用的軟件設計模式,做了匯總,目錄如下:(考慮到內容篇幅較大,為了便于大家閱讀,將軟件設計模式系列(共23個)拆分成四篇文章,每篇文章講解六個設計模式,采用不同的顏色區(qū)分,便于快速消化記憶)本文,主要講解模板模式、策略模式、狀態(tài)模式、觀察者模式、訪問者模式、備忘錄模式1、...

??我將常用的軟件設計模式,做了匯總,目錄如下:

看完這篇,code?review?誰敢噴你代碼寫的爛?懟回去!

(考慮到內容篇幅較大,為了便于大家閱讀,將軟件設計模式系列(共23個)拆分成四篇文章,每篇文章講解六個設計模式,采用不同的顏色區(qū)分,便于快速消化記憶)


本文,主要講解模板模式、策略模式、狀態(tài)模式觀察者模式、訪問者模式、備忘錄模式

1、模板模式

定義:

定義一個操作中的算法的骨架,將一些步驟延遲到子類中。模板模式使得子類可以不改變一個算法的結構即可重定義該算法的某些特定步驟。

優(yōu)點:1、封裝不變部分,擴展可變部分。2、提取公共代碼,便于維護。3、行為由父類控制,子類實現(xiàn)。缺點:每一個不同的實現(xiàn)都需要一個子類來實現(xiàn),導致類的個數增加,維護成本高。

核心思路:

  • AbstractTemplate:定義一個完整的框架,方法的調用順序已經確定,但會定義一些抽象的方法留給子類去實現(xiàn)
  • AHandler:具體的業(yè)務子類,實現(xiàn)AbstractTemplate中定義的抽象方法,從而形成一個完整的流程邏輯
看完這篇,code?review?誰敢噴你代碼寫的爛?懟回去!

代碼示例:

public?TradeFlowActionResult?execute(TradeFlowActionParam?param,?Map?context)?throws?ServiceException?{
????try?{????//?業(yè)務邏輯校驗
????????this.validateBusinessLogic(param,?context);
????}?catch?(ServiceException?ex)?{
????????sendGoodsLog.info("SendGoodsAction->validateBusinessLogic?got?exception.?param?is?"? ?param,?ex);
????????throw?ex;
????}?catch?(RuntimeException?ex)?{
????????sendGoodsLog.info("SendGoodsAction->validateBusinessLogic?got?runtime?exception.?param?is?"? ?param,?ex);
????????throw?ex;
????}
????try?{
????????//?賣家發(fā)貨業(yè)務邏輯
????????this.sendGoods(param,?context);
????}?catch?(ServiceException?ex)?{
????????sendGoodsLog.info("SendGoodsAction->sendGoods?got?exception.?param?is?"? ?param,?ex);
????????throw?ex;
????}?catch?(RuntimeException?ex)?{
????????sendGoodsLog.info("SendGoodsAction->sendGoods?got?runtime?exception.?param?is?"? ?param,?ex);
????????throw?ex;
????}
????try?{
????????//?補充業(yè)務(結果不影響核心業(yè)務)
????????this.addition(param,?context);
????}?catch?(ServiceException?ex)?{
????????sendGoodsLog.info("SendGoodsAction->addition?got?exception.?param?is?"? ?param,?ex);
????????throw?ex;
????}?catch?(RuntimeException?ex)?{
????????sendGoodsLog.info("SendGoodsAction->addition?got?runtime?exception.?param?is?"? ?param,?ex);
????????throw?ex;
????}
????//?處理結果
????return?null;
}
上面提到的三個抽象方法(業(yè)務邏輯校驗、賣家發(fā)貨業(yè)務邏輯、補充業(yè)務)都是在子類中實現(xiàn)的。即控制了主流程結構,又不失靈活性,可以讓使用者在其基礎上定制開發(fā)。如果有新的業(yè)務玩法進來,原來的流程滿足不了需求,我們可以基于模板類編寫新的子類。

適用場景:

  • 希望控制算法的主流程,不能隨意變更框架,但又想保留子類業(yè)務的個性擴展。
  • 去除重復代碼。保留父類通用的代碼邏輯,讓子類不再需要重復處理公用邏輯,只關注特定邏輯,起到去除子類中重復代碼的目的。
  • 案例很多,比如 Jenkins 的拉取代碼、編譯、打包、發(fā)布、部署的流程作為一個通用的流程,不同系統(tǒng)(java、python、nodejs等)可以根據自身的需求開發(fā),定制自己的持續(xù)發(fā)布流程。

2、策略模式

定義:

定義一系列算法,并將每種算法分別放入獨立的類中,以使算法的對象能夠相互替換。

由客戶端自己決定在什么樣的情況下使用哪些具體的策略。

核心思路:

  • 上下文信息類(Context):使用不同的策略環(huán)境,根據自身的條件選擇不同的策略實現(xiàn)類來完成所需要的操作。他持有一個策略實例的引用。
  • 抽象策略類(Strategy):抽象策略,定義每個策略都要實現(xiàn)的方法
  • 具體策略類(A Realize):負責實現(xiàn)抽象策略中定義的策略方法。
看完這篇,code?review?誰敢噴你代碼寫的爛?懟回去!


代碼示例:

/**
?*?@author 微信公眾號:微觀技術
?*/
public?interface?PromotionStrategy?{
????//?活動類型
????String?promotionType();
????//?活動優(yōu)惠
????int?recommand(String?productId);
}

public?class?FullSendPromotion?implements?PromotionStrategy?{
????@Override
????public?String?promotionType()?{
????????return?"FullSend";
????}

????@Override
????public?int?recommand(String?productId)?{
????????System.out.println("參加滿送活動");
????????return?0;
????}
}

public?class?FullReducePromotion?implements?PromotionStrategy?{
????@Override
????public?String?promotionType()?{
????????return?"FullReduce";
????}

????@Override
????public?int?recommand(String?productId)?{
????????System.out.println("參加滿減活動");
????????return?0;
????}
}

@author 微信公眾號:微觀技術
public?class?Context?{

????private?static?List?promotionStrategyList?=?new?ArrayList<>();
????static?{
????????promotionStrategyList.add(new?FullReducePromotion());
????????promotionStrategyList.add(new?FullSendPromotion());
????}
????public?void?recommand(String?promotionType,?String?productId)?{
????????PromotionStrategy?promotionStrategy?=?null;
????????//?找到對應的策略類
????????for?(PromotionStrategy?temp?:?promotionStrategyList)?{
????????????if?(temp.promotionType().equals(promotionType))?{
????????????????promotionStrategy?=?temp;
????????????}
????????}
????????//?策略子類調用
????????promotionStrategy.recommand(productId);
????}

首先,定義活動策略的接口類PromotionStrategy,定義接口方法,每一種具體的策略算法都要實現(xiàn)該接口,FullSendPromotionFullReducePromotion。

Context負責存儲和使用策略,匯集了所有的策略子類。并根據傳入的參數,匹配到具體的策略子類,然后調用recommand方法,處理具體的業(yè)務。

使用策略的好處:

  • 提升代碼的可維護性。不同策略類隔離,互不影響。每一次新增策略時都通過新增類來進行隔離,避免了if-else超大的復雜類
  • 動態(tài)快速地替換更多的算法。由于調度策略與算法實現(xiàn)分離,且接口規(guī)范固定,我們可以靈活的調整選擇不同的策略子類。
適用場景:

  • 壓縮文件,提供了 gzip、zip 、rar 等格式,由客戶端自己選擇哪一種壓縮策略。不同策略可以相互替換。
  • 營銷活動,根據策略路由選擇不同的活動玩法,不同的營銷活動隔離,滿足開閉原則。
  • 選擇權交給了客戶端,適合那些經常調整策略的to C 業(yè)務,靈活性高。

3、狀態(tài)模式

定義:

一種行為設計模式,讓你能在一個對象的內部狀態(tài)變化時改變其行為,使其看上去就像改變了自身所屬的類一樣。

通過定義一系列狀態(tài)的變化來控制行為的變化。以電商為例,用戶的訂單會經歷以下這些狀態(tài):已下單、已付款、已發(fā)貨、派送中、待取件、已簽收、交易成功、交易關閉等狀態(tài)。

核心思路:

  • 上下文信息類(OrderContext):存儲當前狀態(tài)的類,對外提供更新狀態(tài)的方法。
  • 抽象狀態(tài)類(OrderState):可以是一個接口或抽象類,用于聲明狀態(tài)更新時執(zhí)行哪些操作
  • 具體狀態(tài)類(MakeOrderState、PayOrderState、ReceiveGoodOrderState):實現(xiàn)抽象狀態(tài)類定義的方法,根據具體的場景來指定對應狀態(tài)改變后的代碼實現(xiàn)邏輯。
看完這篇,code?review?誰敢噴你代碼寫的爛?懟回去!

代碼示例:

/**
?*?@author 微信公眾號:微觀技術
?*?訂單狀態(tài),接口定義(擴展實現(xiàn)若干不同狀態(tài)的子類)
?*/
public?interface?OrderState?{
????void?handle(OrderContext?context);
}

//?下單
public?class?MakeOrderState?implements?OrderState?{
????public?static?MakeOrderState?instance?=?new?MakeOrderState();
????@Override
????public?void?handle(OrderContext?context)?{

????????System.out.println("1、創(chuàng)建訂單");
????????context.setCurrentOrderState(PayOrderState.instance);
????}
}

//?付款、確認收貨,實現(xiàn)類相似,這里省略。。。。

//?訂單上下文
public?class?OrderContext?{
????private?OrderState?currentOrderState;

????public?OrderContext(OrderState?currentOrderState)?{
????????if?(currentOrderState?==?null)?{
????????????this.currentOrderState?=?new?MakeOrderState();
????????}?else?{
????????????this.currentOrderState?=?currentOrderState;
????????}
????}

????public?void?setCurrentOrderState(OrderState?currentOrderState)?{
????????this.currentOrderState?=?currentOrderState;
????}

????public?void?execute()?{
????????currentOrderState.handle(this);
????}
}
看完這篇,code?review?誰敢噴你代碼寫的爛?懟回去!

運行結果:

1、創(chuàng)建訂單
2、支付寶付款
3、確認收到貨物
狀態(tài)模式設計的核心點在于找到合適的抽象狀態(tài)以及狀態(tài)之間的轉移關系,通過改變狀態(tài)來達到改變行為的目的。

適用場景:

  • 業(yè)務需要根據狀態(tài)的變化,進行不同的操作。比如:電商下單的全流程
  • 不希望有大量的if-else代碼堆在一起,希望不同的狀態(tài)處理邏輯隔離,遵守開閉原則

4、觀察者模式

定義:

也稱 發(fā)布-訂閱模式,是一種通知機制,當一個對象改變狀態(tài)時,它的所有依賴項都會自動得到通知和更新。讓發(fā)送通知的一方(被觀察者)和接收通知的一方(觀察者,支持多個)能彼此分離,互不影響,該模式在軟件開發(fā)中非常流行。

像我們常見的KafkaRocketMQ等消息中間件都是采用這種架構模式,還有SpringApplicationEvent 異步事件驅動,有很好的低耦合特性。

類似其他叫法:

  • 發(fā)布者 --- 訂閱者
  • 生產者 --- 消費者
  • 事件發(fā)布 --- 事件監(jiān)聽
核心思路:

  • 發(fā)布者(Publisher):定義一系列接口,用來管理和觸發(fā)訂閱者
  • 具體發(fā)布者(PublisherImpl):具體實現(xiàn)類,實現(xiàn)Publisher接口定義的方法
  • 訂閱者(Observer):觀察者接口,當發(fā)布者發(fā)布消息或事件時,會通知到訂閱者進行處理。
  • 具體訂閱者(WeixinObserver、EmailObserver):Observer的子類,用來處理具體的業(yè)務邏輯
看完這篇,code?review?誰敢噴你代碼寫的爛?懟回去!

代碼示例:

/**
?*?@author 微信公眾號:微觀技術
?*?
?*?被觀察者
?*/
public?interface?Publisher?{
????void?add(Observer?observer);
????void?remove(Observer?observer);
????void?notify(Object?object);
}

public?class?PublisherImpl?implements?Publisher?{
????private?List?observerList?=?new?ArrayList<>();
????@Override
????public?void?add(Observer?observer)?{
????????observerList.add(observer);
????}
????@Override
????public?void?remove(Observer?observer)?{
????????observerList.remove(observer);
????}
????@Override
????public?void?notify(Object?object)?{
????????System.out.println("創(chuàng)建訂單,并發(fā)送通知事件");
????????observerList.stream().forEach(t?->?t.handle());
????}
}

//?觀察者接口
public?interface?Observer?{
????public?void?handle();
}

//?觀察者子類
public?class?EmailObserver?implements?Observer?{
????@Override
????public?void?handle()?{
????????System.out.println("發(fā)送郵件通知!");
????}
}
觀察者模式的核心精髓:被觀察者定義了一個通知列表,收集了所有的觀察者對象,當被觀察者需要發(fā)出通知時,就會通知這個列表的所有觀察者

適用場景:

  • 當一個對象狀態(tài)的改變需要改變其他對象時。比如:訂單支付成功后,需要通知扣減賬戶余額
  • 一個對象發(fā)生改變時只想要發(fā)送通知,而不需要知道接收者是誰。比如:微博feed流,粉絲能拉到最新微博
  • 代碼的擴展性強,如果需要新增一個觀察者業(yè)務處理,只需新增一個子類觀察者,并注入到被觀察者的通知列表即可,代碼的耦合性非常低。

5、訪問者模式

定義:

訪問者模式是一種將操作與對象結構分離的軟件設計模式,允許在運行時將一個或多個操作應用于一組對象。

核心思路:

  • 行為接口(RouterVisitor):定義對每個 Element 訪問的行為,方法參數就是被訪問的元素,它的方法個數理論上與元素的個數是一樣的。
  • 行為接口實現(xiàn)類(LinuxRouterVisitor、WindowRouterVisitor):它需要給出對每一個元素類訪問時所產生的具體行為。
  • 元素接口(RouterElement):定義一個可以獲取訪問操作的接口,使客戶端對象能夠“訪問”的入口點。
  • 元素接口實現(xiàn)類(JhjRouterElement、LyqRouterElement):將訪問者RouterVisitor傳遞給此對象作為參數。
看完這篇,code?review?誰敢噴你代碼寫的爛?懟回去!

代碼示例:

/**
?*?@author 微信公眾號:微觀技術
?*?定義行為動作
?*/
public?interface?RouterVisitor?{
????//?交換機,發(fā)送數據
????void?sendData(JhjRouterElement?jhjRouterElement);
????//?路由器,發(fā)送數據
????void?sendData(LyqRouterElement?lyqRouterElement);
}

public?class?LinuxRouterVisitor?implements?RouterVisitor?{
????@Override
????public?void?sendData(JhjRouterElement?jhjRouterElement)?{
????????System.out.println("Linux?環(huán)境下,交換機發(fā)送數據");
????}

????@Override
????public?void?sendData(LyqRouterElement?lyqRouterElement)?{
????????System.out.println("Linux?環(huán)境下,路由器發(fā)送數據");
????}
}

public?class?WindowRouterVisitor?implements?RouterVisitor?{
???//?省略。。。
}


/**
?*?@author 微信公眾號:微觀技術
?*?
?*?路由元素
?*/
public?interface?RouterElement?{
????//?發(fā)送數據
????void?sendData(RouterVisitor?routerVisitor);
}
public?class?JhjRouterElement?implements?RouterElement?{

????@Override
????public?void?sendData(RouterVisitor?routerVisitor)?{
????????System.out.println("交換機開始工作。。。");
????????routerVisitor.sendData(this);
????}
}
public?class?LyqRouterElement?implements?RouterElement?{
?//?省略。。。
}
適用場景:

  • 動態(tài)綁定不同的對象和對象操作
  • 通過行為與對象結構的分離,實現(xiàn)對象的職責分離,提高代碼復用性

6、備忘錄模式

定義:

也叫快照模式,用來存儲另外一個對象內部狀態(tài)的快照,便于以后可以恢復。

核心思路:

  • 原始對象(Originator):除了創(chuàng)建自身所需要的屬性和業(yè)務邏輯外,還通過提供方法 bak()restore(memento) 來保存和恢復對象副本。
  • 備忘錄(Memento):用于保存原始對象的所有屬性狀態(tài),以便在未來進行恢復操作。
看完這篇,code?review?誰敢噴你代碼寫的爛?懟回去!

代碼示例:

/**
?*?@author 微信公眾號:微觀技術
?*?原始對象
?*/
@Data
public?class?Originator?{
????private?Long?id;
????private?String?productName;
????private?String?picture;
????//?創(chuàng)建快照
????public?Memento?bak()?{
????????return?new?Memento(id,?productName,?picture);
????}
????//恢復
????public?void?restore(Memento?m)?{
????????this.id?=?m.getId();
????????this.productName?=?m.getProductName();
????????this.picture?=?m.getPicture();
????}
}


//?快照
@Data
@AllArgsConstructor
public?class?Memento?{
????private?Long?id;
????private?String?productName;
????private?String?picture;
}
適用場景:

  • 在線編輯器,不小心關閉瀏覽器,重新打開頁面,可以從草稿箱恢復之前內容
  • 不希望外界直接訪問對象的內部狀態(tài),比如:物流包裹
  • 另外像操作系統(tǒng)自動備份,數據庫的SAVEPOINT

寫在最后

設計模式很多人都學習過,但項目實戰(zhàn)時總是暈暈乎乎,原因在于沒有了解其核心是什么,底層邏輯是什么,《設計模式:可復用面向對象的基礎》有講過,

在設計中思考什么應該變化,并封裝會發(fā)生變化的概念。

軟件架構的精髓:找到變化,封裝變化。

業(yè)務千變萬化,沒有固定的編碼答案,千萬不要硬套設計模式。無論選擇哪一種設計模式,盡量要能滿足SOLID原則,自我review是否滿足業(yè)務的持續(xù)擴展性。有句話說的好,“不論白貓黑貓,能抓老鼠就是好貓?!?/span>

本站聲明: 本文章由作者或相關機構授權發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點,本站亦不保證或承諾內容真實性等。需要轉載請聯(lián)系該專欄作者,如若文章內容侵犯您的權益,請及時聯(lián)系本站刪除。
換一批
延伸閱讀

LED驅動電源的輸入包括高壓工頻交流(即市電)、低壓直流、高壓直流、低壓高頻交流(如電子變壓器的輸出)等。

關鍵字: 驅動電源

在工業(yè)自動化蓬勃發(fā)展的當下,工業(yè)電機作為核心動力設備,其驅動電源的性能直接關系到整個系統(tǒng)的穩(wěn)定性和可靠性。其中,反電動勢抑制與過流保護是驅動電源設計中至關重要的兩個環(huán)節(jié),集成化方案的設計成為提升電機驅動性能的關鍵。

關鍵字: 工業(yè)電機 驅動電源

LED 驅動電源作為 LED 照明系統(tǒng)的 “心臟”,其穩(wěn)定性直接決定了整個照明設備的使用壽命。然而,在實際應用中,LED 驅動電源易損壞的問題卻十分常見,不僅增加了維護成本,還影響了用戶體驗。要解決這一問題,需從設計、生...

關鍵字: 驅動電源 照明系統(tǒng) 散熱

根據LED驅動電源的公式,電感內電流波動大小和電感值成反比,輸出紋波和輸出電容值成反比。所以加大電感值和輸出電容值可以減小紋波。

關鍵字: LED 設計 驅動電源

電動汽車(EV)作為新能源汽車的重要代表,正逐漸成為全球汽車產業(yè)的重要發(fā)展方向。電動汽車的核心技術之一是電機驅動控制系統(tǒng),而絕緣柵雙極型晶體管(IGBT)作為電機驅動系統(tǒng)中的關鍵元件,其性能直接影響到電動汽車的動力性能和...

關鍵字: 電動汽車 新能源 驅動電源

在現(xiàn)代城市建設中,街道及停車場照明作為基礎設施的重要組成部分,其質量和效率直接關系到城市的公共安全、居民生活質量和能源利用效率。隨著科技的進步,高亮度白光發(fā)光二極管(LED)因其獨特的優(yōu)勢逐漸取代傳統(tǒng)光源,成為大功率區(qū)域...

關鍵字: 發(fā)光二極管 驅動電源 LED

LED通用照明設計工程師會遇到許多挑戰(zhàn),如功率密度、功率因數校正(PFC)、空間受限和可靠性等。

關鍵字: LED 驅動電源 功率因數校正

在LED照明技術日益普及的今天,LED驅動電源的電磁干擾(EMI)問題成為了一個不可忽視的挑戰(zhàn)。電磁干擾不僅會影響LED燈具的正常工作,還可能對周圍電子設備造成不利影響,甚至引發(fā)系統(tǒng)故障。因此,采取有效的硬件措施來解決L...

關鍵字: LED照明技術 電磁干擾 驅動電源

開關電源具有效率高的特性,而且開關電源的變壓器體積比串聯(lián)穩(wěn)壓型電源的要小得多,電源電路比較整潔,整機重量也有所下降,所以,現(xiàn)在的LED驅動電源

關鍵字: LED 驅動電源 開關電源

LED驅動電源是把電源供應轉換為特定的電壓電流以驅動LED發(fā)光的電壓轉換器,通常情況下:LED驅動電源的輸入包括高壓工頻交流(即市電)、低壓直流、高壓直流、低壓高頻交流(如電子變壓器的輸出)等。

關鍵字: LED 隧道燈 驅動電源
關閉