国产精品电影_久久视频免费_欧美日韩国产激情_成年人视频免费在线播放_日本久久亚洲电影_久久都是精品_66av99_九色精品美女在线_蜜臀a∨国产成人精品_冲田杏梨av在线_欧美精品在线一区二区三区_麻豆mv在线看

3年工作必備 裝飾器模式

開發 前端
裝飾器模式(Decorator Pattern)也叫作包裝器模式(Wrapper Pattern),指在不改變原有對象的基礎上,動態地給一個對象添加一些額外的職責。就增加功能來說,裝飾器模式相比生成子類更為靈活,屬于結構型設計模式。

[[403421]]

 今天我給大家分享設計模式中的裝飾器模式。用貼切的生活故事,以及真實項目場景來講設計模式,最后用一句話來總結這個設計模式。

故事

古話說的好:人靠衣裳馬靠鞍。下面先帶大家來熟悉這句話的背景:

人靠衣裝馬靠鞍,狗配鈴鐺跑的歡出自沈自晉《望湖亭記》第十出:“雖然如此,佛靠金裝,人靠衣裝,打扮也是很要緊的。”《醒世恒言》卷一?兩縣令競義婚孤女:”常言道:’佛是金裝,人是衣裝,世人眼孔淺的多,只有皮相,沒有骨相。’”俗語我們會說成人靠衣裝馬靠鞍。

這個經典故事,讓我想起了一個設計模式:裝飾器模式。

什么是裝飾器模式呢?請聽老田慢慢道來。

裝飾器模式概述

裝飾器模式(Decorator Pattern)也叫作包裝器模式(Wrapper Pattern),指在不改變原有對象的基礎上,動態地給一個對象添加一些額外的職責。就增加功能來說,裝飾器模式相比生成子類更為靈活,屬于結構型設計模式。

英文:

Attach additional responsibilities to an object dynamicallykeeping the same interface.Decorators provide a flexible alternativeto subclassing for extending functionality.

裝飾器模式提供了比繼承更有彈性的替代方案(擴展原有對象的功能)將功能附加到對象上。因此,裝飾器模式的核心是功能擴展。使用裝飾器模式可以透明且動態地擴展類的功能。

生活中的案例

一套毛坯房,沒有裝修之前,看起來非常難看,但只要稍微裝修一番,那就漂亮多了,并且能洗澡、睡覺、做飯等,但本質還是房子。

一輛汽車,原本就是一輛代步的車,但是瑪麗加大,配置提升,然后就成了豪車,但本質還是一輛代步的車。

一個女生,原本很平凡,長相一般,但是經過一番化妝,再穿點好看的衣服,然后就成了很多人心中的女神了。

總之,經過點裝飾后,就是不一樣了,功能增強了。

裝飾器模式通用代碼實現

我們還是用代碼來實現一把,程序員都喜歡先搞個demo,然后再慢慢研究。

  1. //抽象組件 
  2. public abstract class Component { 
  3.     public abstract void operation(); 
  4. //具體組件 
  5. public class ConcreteComponent extends Component { 
  6.     @Override 
  7.     public void operation() { 
  8.         System.out.println("ConcreteComponent operation"); 
  9.     } 
  10. //裝飾器抽象 
  11. public abstract class Decorator extends Component { 
  12.  
  13.     protected Component component; 
  14.  
  15.     public Decorator(Component component) { 
  16.         this.component = component; 
  17.     } 
  18.  
  19.     @Override 
  20.     public void operation() { 
  21.         component.operation(); 
  22.     } 
  23. //具體裝飾器 
  24. public class ConcreteDecorator extends Decorator { 
  25.     public ConcreteDecorator(Component component) { 
  26.         super(component); 
  27.     } 
  28.  
  29.     @Override 
  30.     public void operation() { 
  31.         System.out.println("開始前搞點事"); 
  32.         super.operation(); 
  33.         System.out.println("結束后搞點事"); 
  34.     } 
  35. //測試 
  36. public class Client { 
  37.     public static void main(String[] args) { 
  38.         Component component = new ConcreteDecorator(new ConcreteComponent()); 
  39.         component.operation(); 
  40.     } 

運行結果:

  1. 開始前搞點事 
  2. ConcreteComponent operation 
  3. 結束后搞點事 

以上便是裝飾器模式的通用代碼實現,下面我們來分析一下。

裝飾器模式UML圖

從UML途中可以看出,其中的角色

裝飾器模式中的角色

  • 抽象組件(Component):可以是一個接口或者抽象類,充當被裝飾類的原始對象,規定了被裝飾對象的行為。
  • 具體組件(ConcreteComponent):實現/繼承Component的一個具體對象,即被裝飾對象。
  • 抽象裝飾器(Decorator):通用的裝飾ConcreteComponent的裝飾器,其內部必然有一個屬性指向Component;其實現一般是一個抽象類,主要為了讓其子類按照其構造形式傳入一個Component,這是強制的通用行為。如果系統中裝飾邏輯單一,則并不需要實現許多裝飾器,可以直接省略該類,而直接實現一個具體裝飾器即可。
  • 具體裝飾器(ConcreteDecorator):Decorator的具體實現類,理論上,每個ConcreteDecorator都擴展了Component對象的一種功能。

小結

裝飾器模式角色分配符合設計模式的里氏替換原則、依賴倒置原則,從而使得其具備很強的擴展性,最終滿足開閉原則。

裝飾器模式的實現原理是,讓裝飾器實現與被裝飾類(例如ConcreteComponent)相同的接口(例如Component),使得裝飾器與被擴展類類型一致,并在構造函數中傳入該接口對象,然后在實現這個接口的被包裝類對象的現有功能上添加新功能。由于裝飾器與被包裝類屬于同一類型(均為Component),且構造函數的參數為其實現接口類(Component),因此裝飾器模式具備嵌套擴展功能,這樣就能使用裝飾器模式一層一層地對底層被包裝類進行功能擴展了。

實戰

在實際開發中,都會存在系統與系統之間的調用,假如說我們現在有個支付功能,現在一切都是沒問題的,但是 我們此時需要對發起支付前的請求參數和支付后的相應參數。進行統一處理,原功能不變,只是在原功能上做了一點擴展(增強)。

老功能代碼如下:

  1. /** 
  2.  * @author 田先生 
  3.  * @date 2021-06-02 
  4.  * 
  5.  * 歡迎關注公眾號:java后端技術全棧 
  6.  */ 
  7. public interface IOrderPayService { 
  8.     String payment(Long orderId, BigDecimal amount); 
  9. public class OrderPayServiceImpl implements IOrderPayService { 
  10.  
  11.     @Override 
  12.     public String payment(Long orderId, BigDecimal amount) { 
  13.         //先調用余額查詢是否足夠 
  14.         System.out.println("發起支付,訂單號:" + orderId + ", 支付金額:" + amount.toString()); 
  15.         //調用支付系統 
  16.         String result = "訂單id=" + orderId + "支付完成"
  17.         System.out.println("支付結果:" + result); 
  18.         return result; 
  19.     } 
  20. public class OrderClient { 
  21.     public static void main(String[] args) { 
  22.         IOrderPayService orderPayService = new OrderPayServiceImpl(); 
  23.         orderPayService.payment(10001L,new BigDecimal("5000")); 
  24.     } 

運行輸出:

  1. 發起支付,訂單號:10001, 支付金額:5000 
  2. 支付結果:訂單id=10001支付完成 

新需求,需要把這些請求參數和相應結果進行單獨搜集處理,此時為了不影響原有功能,于是我們可以對其進行功能增強。

  1. /** 
  2.  * @author 田先生 
  3.  * @date 2021-06-02 
  4.  * 
  5.  * 歡迎關注公眾號:java后端技術全棧 
  6.  */ 
  7. public class OrderPayDecorator implements IOrderPayService { 
  8.  
  9.     private IOrderPayService orderPayService; 
  10.  
  11.     public OrderPayDecorator(IOrderPayService orderPayService) { 
  12.         this.orderPayService = orderPayService; 
  13.     } 
  14.  
  15.     @Override 
  16.     public String payment(Long orderId, BigDecimal amount) { 
  17.         System.out.println("把這個訂單信息(發起支付)" + "訂單id=" + orderId + "支付金額=" + amount.toString() + " 【發送給MQ】"); 
  18.         String result = orderPayService.payment(orderId, amount); 
  19.         System.out.println("把訂單支付結果信息" + result + " 【發送給MQ】"); 
  20.         return result; 
  21.     } 
  22. public class OrderClient { 
  23.     public static void main(String[] args) { 
  24.         IOrderPayService orderPayService =new OrderPayDecorator(new OrderPayServiceImpl()); 
  25.         orderPayService.payment(10001L,new BigDecimal("5000")); 
  26.     } 

運行輸出:

  1. 把這個訂單信息(發起支付)訂單id=10001支付金額=5000 【發送給MQ】 
  2. 發起支付,訂單號:10001, 支付金額:5000 
  3. 支付結果:訂單id=10001支付完成 
  4. 把訂單支付結果信息訂單id=10001支付完成 【發送給MQ】 

整個過程,大家有沒有發現,我們并沒動原有的代碼,僅僅只是做了功能增強。

裝飾器模式在新項目中基本上不會用到,通常都是在老項目中使用,因為已有的功能不變,只是做了一些功能增強。

大神們是怎么用的

裝飾器設計模式在JDK源碼、Spring源碼以及Mybatis源碼中都有。

JDK源碼中

裝飾器模式比較經典的應用就是 JDK 中的 java.io 包下,InputStream、OuputStream、Reader、Writer 及它們的子類。

以 InputStream 為例

  • FileInputStream 是 InputStream 的子類,用來讀取文件字節流
  • BufferedInputStream 是 InputStream 的子類的子類,可緩存的字節流
  • DataInputStream 也是 InputStream 的子類的子類,可直接讀取 Java 基本類型的字節流

UML圖

DataInputStream 中構造器入參便是自己的父類(InputStream)。

如果希望提供一個可以讀取文件 + 可緩存的字節流,使用繼承方式,就需要派生 FileBufferedInputStream;

如果希望提供一個可以讀取文件 + 直接讀取基本類型的字節流,使用繼承方式,就需要派生 FileDataInputStream。

字節流功能的增強還包括支持管道 pipe、字節數組 bytearray、字節對象 object、字節流字符流的轉換 等維度,如果用繼承方式,那類的層級與種類會多到爆炸。

為了解決問題,這邊就使用了裝飾器模式。

Spring源碼中

在Spring中,我們可以嘗試理解一下TransactionAwareCacheDecorator類,這個類主要用來處理事務緩存,代碼如下。

  1. public class TransactionAwareCacheDecorator implements Cache { 
  2.     private final Cache targetCache; 
  3.     //構造方法入參類型為自己的父類(接口類型) 
  4.     public TransactionAwareCacheDecorator(Cache targetCache) { 
  5.         Assert.notNull(targetCache, "Target Cache must not be null"); 
  6.         this.targetCache = targetCache; 
  7.     } 
  8.  
  9.     public Cache getTargetCache() { 
  10.         return this.targetCache; 
  11.     } 
  12.     //... 

TransactionAwareCacheDecorator就是對Cache的一個包裝,因此,這里也是使用了裝飾器模式。

Mybatis源碼中

MyBatis中關于Cache和CachingExecutor接口的實現類也使用了裝飾者設計模式。Executor是MyBatis執行器,是MyBatis 調度的核心,負責SQL語句的生成和查詢緩存的維護;CachingExecutor是一個Executor的裝飾器,給一個Executor增加了緩存的功能。此時可以看做是對Executor類的一個增強,故使用裝飾器模式是合適的。

在CachingExecutor 中

  1. public class CachingExecutor implements Executor { 
  2.   //持有組件對象 
  3.   private Executor delegate; 
  4.   private TransactionalCacheManager tcm = new TransactionalCacheManager(); 
  5.     //構造方法,傳入組件對象 
  6.   public CachingExecutor(Executor delegate) { 
  7.     this.delegate = delegate; 
  8.     delegate.setExecutorWrapper(this); 
  9.   } 
  10.   @Override 
  11.   public int update(MappedStatement ms, Object parameterObject) throws SQLException { 
  12.       //轉發請求給組件對象,可以在轉發前后執行一些附加動作 
  13.     flushCacheIfRequired(ms); 
  14.     return delegate.update(ms, parameterObject); 
  15.   } 
  16.   //... 
  17.  } 

總結

看完裝飾器模式后,你是否有感覺,裝飾器模式和代理模式非常的相像,下面我們就來做個對比。

1.裝飾器模式可以理解為一種特殊的代理模式。

2.裝飾器模式強調自身的功能擴展,透明的擴展(即用戶想增強什么功能就增強什么功能),可動態定制的擴展。

3.代理模式強調的是代理過程的控制。

優點

  • 裝飾器是繼承的有力補充,比繼承靈活,在不改變原有對象的情況下,動態地給一個對象擴展功能,即插即用。
  • 通過使用不同裝飾類及這些裝飾類的排列組合,可以實現不同效果。
  • 裝飾器模式完全遵守開閉原則。

缺點

  • 會出現更多的代碼、更多的類,增加程序的復雜性。
  • 動態裝飾在多層裝飾時會更復雜。
  • 好了,今天的分享就到此結束,希望你能徹底掌握裝飾器模式,如果還有疑問,或者技術探討之類的,歡迎加我微信,一起探討。

文轉載自微信公眾號「Java后端技術全棧」,可以通過以下二維碼關注。轉載本文請聯系Java后端技術全棧公眾號。

 

責任編輯:武曉燕 來源: Java后端技術全棧
相關推薦

2023-09-04 13:14:00

裝飾器設計模式

2023-12-13 13:28:16

裝飾器模式Python設計模式

2022-01-19 08:21:12

設計裝飾器模式

2025-01-22 15:58:46

2024-02-23 12:11:53

裝飾器模式對象

2022-09-14 08:16:48

裝飾器模式對象

2024-04-10 12:27:43

Python設計模式開發

2021-07-12 10:24:36

Go裝飾器代碼

2020-12-01 07:16:05

重學設計模式

2022-03-25 11:01:28

Golang裝飾模式Go 語言

2023-02-07 07:47:52

Python裝飾器函數

2010-02-01 17:50:32

Python裝飾器

2022-12-31 19:20:15

JavaScriptstage 3裝飾器

2024-02-26 00:00:00

TypeScript裝飾器decorators

2009-12-18 10:47:16

Ruby裝飾模式

2022-11-26 00:00:06

裝飾者模式Component

2023-08-29 08:44:38

裝飾器組合模式

2011-10-12 10:07:52

2011-10-11 10:05:09

微軟免費服務器

2021-06-02 08:17:05

門面模式設計
點贊
收藏

51CTO技術棧公眾號

久久青青草原一区二区| 国产精品99久久久久久久久久久久 | 日韩a在线看| 国产网站观看9久| 污视频网站在线免费| 国产精品视频免费看| 欧美日韩亚洲一区二区三区在线观看 | 精品69视频一区二区三区Q| 99久久99精品久久久久久| 高清视频一区| 亚洲高清在线观看一区| 9191在线| 亚洲综合成人在线| 国产精品69页| 成人动漫视频在线| 日韩国产精品毛片| 香蕉久久夜色精品国产| 国产色视频一区| 好吊妞国产欧美日韩免费观看网站 | 久久综合激情| 91在线观看网站| 国产精品欧美三级在线观看| xxxxx成人.com| 日韩一级高清毛片| 免费观看的av网站| 国产欧美日韩精品一区| 专区另类欧美日韩| caoporn国产精品免费公开| 亚洲国产最新| 欧美精品激情视频| 电影一区中文字幕| 福利成人在线观看| 国产日韩精品视频一区| 丝袜老师办公室里做好紧好爽| 久久不射网站| 亚洲人av在线影院| 日本少妇一区二区| 激情中国色综合| 国产精品―色哟哟| 亚洲视频在线观看视频| 青青草国产成人99久久| 欧美亚洲视频在线观看| 欧美亚洲激情视频| 宅男一区二区三区| 动漫av一区| 91在线porny国产在线看| 亚洲aⅴ天堂av在线电影软件| 亚洲午夜一级| 美乳视频一区二区| 乱人伦精品视频在线观看| 好吊色欧美一区二区三区四区| 91久久综合| 亚洲国产精品综合| 精品在线你懂的| 国产91xxx| 成人免费一区二区三区在线观看| 成人黄色免费| 色哟哟一区二区在线观看| 国产精品四虎| 日韩一区二区视频| 日韩av中字| 欧美极品在线视频| 日韩在线第七页| 国偷自产av一区二区三区小尤奈| 日韩av中文字幕一区二区| 喜爱夜蒲2在线| 亚洲国产经典视频| 欧美777四色影视在线 | jizz亚洲| 欧美精品一区视频| 成人免费网站www网站高清| 日韩黄在线观看| 国产麻豆精品| 国产欧美日韩中文| 日韩黄色免费电影| 99精品人妻少妇一区二区| 一区免费观看视频| 91在线视频免费看| 中文字幕久久久| 日韩av影院| 国产伦理一区二区三区| 国产大片一区二区| 成人a视频在线| 精品成a人在线观看| 玖玖精品一区| 成人综合网网址| 日本大胆欧美人术艺术动态| 无码专区aaaaaa免费视频| 一区二区三区在线视频免费观看| 乱人伦中文视频在线| 欧美成人精品在线播放| 你懂的国产精品永久在线| 8x8ⅹ国产精品一区二区二区| 国产精品久久夜| 4438x成人网全国最大| 欧美大尺度激情区在线播放| 欧美91福利在线观看| 美脚丝袜脚交一区二区| 亚洲精品国产一区二区三区四区在线| av中文字幕在线观看| 91精品国产乱码久久久久久蜜臀| 男人的天堂亚洲| 天天干天天操天天做| 日韩精品一区二区三区中文不卡| 精品久久ai电影| eeuss中文| 在线免费观看视频一区| 精品国产乱码一区二区三区 | 欧美女同一区| 91黄色小网站| 精品久久久中文| 久久天堂av| 成人影院天天5g天天爽无毒影院| 99日韩精品| 色成人亚洲网| 欧美xxxx18国产| 欧美gayvideo| 成人欧美一区二区三区在线| 国产精品一色哟哟哟| 成人综合网址| 欧美一区三区三区高中清蜜桃| 国产喂奶挤奶一区二区三区| 国产精品久久久久久妇女| 2019中文在线观看| 久久亚洲影视婷婷| 国产精品成人av| 外国成人直播| 国产精品电影网| 91在线一区二区三区| а√天堂资源地址在线下载| 国产va免费精品高清在线| 国产成人精品www牛牛影视| 91高清在线| 国产精品无码专区在线观看| 91丨porny丨国产入口| 黄色美女视频在线观看| 国产99视频精品免费视频36| 亚洲欧美日本在线| 一区二区免费| 国产精品999视频| 亚洲美女动态图120秒| 欧美专区18| 毛片在线播放网站| 国产日韩av在线| 依依成人精品视频| 欧美日韩一本| 天堂社区在线视频| 久久久国产精品免费| 国产不卡在线播放| 伊人久久精品一区二区三区| 日本一区二区不卡高清更新| 欧美日韩国产系列| 激情欧美一区二区三区| 久久这里精品| 国产精品亚洲综合| 欧美色图片你懂的| 国产精品普通话对白| 天天在线视频色| 精品无码久久久久久久动漫| 色综合久久88色综合天天6| 91精品国产自产拍在线观看蜜 | 国产在线一区二区三区欧美| 亚洲愉拍自拍另类高清精品| 久9re热视频这里只有精品| 少妇性饥渴无码a区免费| 伊人伊成久久人综合网小说 | 国产九色在线| 91久久久精品| 色婷婷av一区二区三区gif| 午夜精品电影| 91官网在线| 人禽交欧美网站免费| 亚洲国产欧美一区二区三区同亚洲| 美女视频网站久久| 日本电影欧美片| 成人小视频在线看| 庆余年2免费日韩剧观看大牛| 亚洲国产成人tv| 亚洲啪啪91| 性国裸体高清亚洲| 苍井空浴缸大战猛男120分钟| 57pao成人国产永久免费| 午夜av区久久| 免费亚洲婷婷| 91九色综合| 色偷偷亚洲第一综合| 91影视免费在线观看| 欧美成人精品1314www| 成人aaaa免费全部观看| 清纯唯美亚洲经典中文字幕| 传媒在线观看| 色一情一乱一伦一区二区三区| 少妇av一区二区三区| 综合电影一区二区三区| 亚洲国产精品久久久天堂| 免费在线看污片| 一本久道中文无码字幕av| 成人精品在线视频| 精品视频中文字幕| 亚洲精品中文字幕在线观看|