每週寫工做總結、工做彙報是許多程序員的傷痛,哈哈。真實狀況是又摸魚了一週,給領導寫工做報告,固然不能直接寫「摸魚」,這時候就須要裝飾模式來對咱們提交的報告作下修飾,甚至領導的評語裏面也給加點美化內容,否則, 這個月的獎金就泡湯了,只能吃土了。程序員
重點:經過建立包裝類,包裹真實對象,達到對真實對象的動態擴展。bash
看下咱們上面的場景用裝飾模式實現的UML圖。markdown
一、WorkReport爲工做報告的抽象類,定義了兩個方法,reportdata()用於查看工做報告的內容,check方法是領導點評的。ide
二、RealReport爲實際的報告類。測試
三、Decorator爲裝飾類的抽象類,通過裝飾後的報告依然得是報告,因此裝飾抽象類繼承自工做報告this
四、DecAddDescript、DecAddComment爲具體的裝飾類。spa
看下代碼實現調試
一、工做報告抽象類code
package com.design.decorator;
public abstract class WorkReport {
public abstract void reportData();
public abstract void check(String comment);
}
複製代碼
二、工做報告orm
package com.design.decorator; public class RealReport extends WorkReport { @Override public void reportData() { System.out.println("工做描述:"); System.out.println("這周的工做是調試了倆個BUG!!"); } @Override public void check(String comment) { System.out.println("評述:"); System.out.println(comment); } } 複製代碼
三、裝飾抽象類,持有工做報告的引用,擴展報告。
package com.design.decorator;
public abstract class Decorator extends WorkReport {
protected WorkReport workReport;
public Decorator(WorkReport workReport){
this.workReport = workReport;
}
}
複製代碼
四、具體的裝飾類,擴展查看報告方法
package com.design.decorator; public class DecAddDescript extends Decorator{ public DecAddDescript(WorkReport workReport) { super(workReport); } @Override public void reportData() { //動態擴展,增長一些描述 super.workReport.reportData(); System.out.println("這周出來的兩個BUG比較詭異!通過各類折騰,費盡九牛二虎之類才搞定的,別看只是兩個bug,工做量可很多!!"); System.out.println(); } @Override public void check(String comment) { super.workReport.check(comment); } } 複製代碼
具體的裝飾類,擴展領導審覈功能
package com.design.decorator; public class DecAddComment extends Decorator { public DecAddComment(WorkReport workReport) { super(workReport); } @Override public void reportData() { workReport.reportData(); } @Override public void check(String comment) { workReport.check(comment); ////動態擴展,悄悄把領導的評語後面增長一些內容 System.out.println("XXX同窗雖然只改兩個BUG,但修復這兩個BUG意義重大,給他全額獎金!!"); } } 複製代碼
五、最終運行
package com.design.decorator; public class TestMain { public static void main(String[] args) { WorkReport workReport = new RealReport(); //裝飾一下描述 WorkReport decAddDescript = new DecAddDescript(workReport); //裝飾一下領導評語,揹着領導偷偷加 WorkReport decACommnet = new DecAddComment(decAddDescript); decACommnet.reportData(); decACommnet.check("修復了兩個bug!!"); } }複製代碼
測試結果
從定義中,咱們就能夠知道裝飾模式的用處了,擴展對象的功能,並且是在不修改原對象的狀況下。
優勢:
一、有力於分離開核心功能與非核心的擴展功能。咱們能夠將核心功能放到實際類上,其餘非核心裝飾類的功能放到裝飾類上。
二、靈活擴展裝飾,如上例子,若是咱們不須要擴展評語,只擴展工做描述,則只須要在裝飾鏈上面,去除評語對象的。只需修改客戶端代碼便可。新增擴展功能,也僅需增長裝飾類。
WorkReport workReport = new RealReport();
//裝飾一下描述
WorkReport decAddDescript = new DecAddDescript(workReport);複製代碼
缺點:
一、裝飾鏈較長狀況下,邏輯比較複雜,不利於閱讀代碼。