Java基于裝飾者模式實(shí)現(xiàn)的染色饅頭案例詳解
本文實(shí)例講述了Java基于裝飾者模式實(shí)現(xiàn)的染色饅頭案例。分享給大家供大家參考,具體如下:
一、模式定義
裝飾者模式,是在不改變原類文件和使用繼承的情況下,動態(tài)擴(kuò)展一個對象功能,它是通過創(chuàng)建一個包裝對象,也就是裝飾來包裝真實(shí)的對象。
裝飾對象和真實(shí)對象有相同接口,這樣客戶端對象就可以和真實(shí)對象相同方式和裝飾對象交互。
裝飾對象包含一個真實(shí)對象的引用。
二、模式舉例
1. 模式分析
我們借用黑心商販制做染色饅頭案例說明這一模式。

2. 裝飾者模式靜態(tài)類圖

3. 代碼示例
3.1 創(chuàng)建饅頭接口——IBread
package com.demo.abs;
/**
* 饅頭加工接口
*
* @author
*
*/
public interface IBread {
// 準(zhǔn)備材料
public void prepair();
// 和面
public void kneadFlour();
// 蒸饅頭
public void steamed();
/**
* 加工饅頭方法
*/
public void process();
}
3.2 正常饅頭實(shí)現(xiàn)——NormalBread
package com.demo.abs;
/**
* 正常饅頭的實(shí)現(xiàn)
*
* @author
*
*/
public class NormalBread implements IBread {
// 準(zhǔn)備材料
public void prepair() {
System.out.println("準(zhǔn)備面粉、水以及發(fā)酵粉...");
}
// 和面
public void kneadFlour() {
System.out.println("和面...");
}
// 蒸饅頭
public void steamed() {
System.out.println("蒸饅頭...香噴噴的饅頭出爐了!");
}
/**
* 加工饅頭方法
*/
public void process() {
// 準(zhǔn)備材料
prepair();
// 和面
kneadFlour();
// 蒸饅頭
steamed();
}
}
3.3 創(chuàng)建抽象裝飾者——AbstractBread
package com.demo.decorator;
import com.demo.abs.IBread;
/**
* 抽象裝飾者
*
* @author
*
*/
public abstract class AbstractBread implements IBread {
// 存儲傳入的IBread對象
private final IBread bread;
public AbstractBread(IBread bread) {
this.bread = bread;
}
// 準(zhǔn)備材料
public void prepair() {
this.bread.prepair();
}
// 和面
public void kneadFlour() {
this.bread.kneadFlour();
}
// 蒸饅頭
public void steamed() {
this.bread.steamed();
}
// 加工饅頭方法
public void process() {
prepair();
kneadFlour();
steamed();
}
}
3.4 創(chuàng)建染色劑裝飾者——CornDecorator
package com.demo.decorator;
import com.demo.abs.IBread;
/**
* 染色的玉米饅頭
*
* @author
*
*/
public class CornDecorator extends AbstractBread {
// 構(gòu)造方法
public CornDecorator(IBread bread) {
super(bread);
}
// 黑心商販 開始染色了
public void paint() {
System.out.println("添加檸檬黃的著色劑...");
}
// 重載父類的和面方法
@Override
public void kneadFlour() {
// 在面粉中加入 染色劑 之后才開始和面
this.paint();
// 和面
super.kneadFlour();
}
}
3.5 創(chuàng)建甜蜜素裝飾者——SweetDecorator
package com.demo.decorator;
import com.demo.abs.IBread;
/**
* 甜蜜素饅頭
*
* @author
*
*/
public class SweetDecorator extends AbstractBread {
// 構(gòu)造方法
public SweetDecorator(IBread bread) {
super(bread);
}
// 黑心商販 開始添加甜蜜素
public void paint() {
System.out.println("添加甜蜜素...");
}
// 重載父類的和面方法
@Override
public void kneadFlour() {
// 在面粉中加入 甜蜜素 之后才開始和面
this.paint();
// 和面
super.kneadFlour();
}
}
3.6 生產(chǎn)甜玉米饅頭——Client
package com.demo;
import com.demo.abs.IBread;
import com.demo.abs.NormalBread;
import com.demo.decorator.CornDecorator;
import com.demo.decorator.SweetDecorator;
/**
* 客戶端應(yīng)用程序
*
* @author
*
*/
public class Client {
/**
* @param args
*/
public static void main(String[] args) {
// 生產(chǎn)裝飾饅頭
System.out.println("\n====開始裝飾饅頭?。?!");
// 創(chuàng)建普通的正常饅頭實(shí)例
// 這是我們需要包裝(裝飾)的對象實(shí)例
IBread normalBread = new NormalBread();
// 下面就開始 對正常饅頭進(jìn)行裝飾了!?。?
// 使用甜蜜素裝飾饅頭
normalBread = new SweetDecorator(normalBread);
// 使用檸檬黃的著色劑裝飾饅頭
normalBread = new CornDecorator(normalBread);
// 生產(chǎn)饅頭信息
normalBread.process();
System.out.println("====裝飾饅頭結(jié)束?。?!");
}
}
4. 運(yùn)行結(jié)果
====開始裝飾饅頭!??!
準(zhǔn)備面粉、水以及發(fā)酵粉...
添加檸檬黃的著色劑...
添加甜蜜素...
和面...
蒸饅頭...香噴噴的饅頭出爐了!
====裝飾饅頭結(jié)束?。。?/p>
三、該模式設(shè)計原則
1 封閉變化部分
2 “開一閉"原則
3 面向抽象編程
4 優(yōu)先使用組合,而非繼承
四、使用場合
1. 當(dāng)我們需要為某個現(xiàn)有對象動態(tài)增加一個新功能或職責(zé)時,可以考慮使用裝飾者模式。
2. 當(dāng)某個對象的職責(zé)經(jīng)常發(fā)生變化或經(jīng)常需要動態(tài)增加職責(zé),避免為了適應(yīng)這樣的變化而增加繼承子類擴(kuò)展的方式,因?yàn)檫@種方式會造成子類膨脹速度過快,難以控制,此時可以使用裝飾者模式。
五、裝飾者模式靜態(tài)類圖

更多關(guān)于java算法相關(guān)內(nèi)容感興趣的讀者可查看本站專題:《Java數(shù)據(jù)結(jié)構(gòu)與算法教程》、《Java操作DOM節(jié)點(diǎn)技巧總結(jié)》、《Java文件與目錄操作技巧匯總》和《Java緩存操作技巧匯總》
希望本文所述對大家java程序設(shè)計有所幫助。
相關(guān)文章
SWT(JFace) Wizard(Eclipse插件編程必備)
SWT(JFace)小制作:Wizard(Eclipse插件編程必備)2009-06-06
Java?Float?保留小數(shù)位精度的實(shí)現(xiàn)
這篇文章主要介紹了Java?Float?保留小數(shù)位精度的實(shí)現(xiàn)方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-12-12
Java8新特性之類型注解_動力節(jié)點(diǎn)Java學(xué)院整理
這篇文章主要介紹了Java8新特性之類型注解的相關(guān)資料,需要的朋友可以參考下2017-06-06
如何修改FeginCilent定義的服務(wù)名到指定服務(wù)
這篇文章主要介紹了修改FeginCilent定義的服務(wù)名到指定服務(wù)的操作,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-07-07
java內(nèi)存異常使用導(dǎo)致full?gc頻繁
Full?GC是Java虛擬機(jī)中垃圾回收的一種方式,它會暫停應(yīng)用程序所有的線程并清理整個堆內(nèi)存。頻繁的Full?GC會導(dǎo)致應(yīng)用程序的性能下降,甚至出現(xiàn)長時間的停頓。Java內(nèi)存異常使用常常是Full?GC頻繁出現(xiàn)的原因之一,如使用大量的靜態(tài)變量、內(nèi)存泄漏等。2023-04-04
解決feignClient調(diào)用時獲取返回對象類型匹配的問題
這篇文章主要介紹了解決feignClient調(diào)用時獲取返回對象類型匹配的問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-06-06
Java實(shí)現(xiàn)克隆的三種方式實(shí)例總結(jié)
這篇文章主要介紹了Java實(shí)現(xiàn)克隆的三種方式,結(jié)合實(shí)例形式總結(jié)分析了java淺復(fù)制、深復(fù)制以及使用serializable實(shí)現(xiàn)深復(fù)制的相關(guān)操作技巧,需要的朋友可以參考下2018-08-08

