博主介紹: ?博主從事應(yīng)用安全和大數(shù)據(jù)領(lǐng)域,有8年研發(fā)經(jīng)驗(yàn),5年面試官經(jīng)驗(yàn),Java技術(shù)專家?
Java知識(shí)圖譜點(diǎn)擊鏈接:體系化學(xué)習(xí)Java(Java面試專題)
???? 感興趣的同學(xué)可以收藏關(guān)注下 ,不然下次找不到喲????
1、什么是裝飾者模式
裝飾者模式(Decorator Pattern)是一種結(jié)構(gòu)型設(shè)計(jì)模式,它允許你向一個(gè)現(xiàn)有的對(duì)象添加新的功能,同時(shí)又不改變其結(jié)構(gòu)。裝飾者模式基于組合而非繼承的原則,它動(dòng)態(tài)地將責(zé)任附加到對(duì)象上。
裝飾者模式涉及到四個(gè)角色:抽象組件、具體組件、抽象裝飾者和具體裝飾者。其中,抽象組件定義了組件的基本功能,具體組件實(shí)現(xiàn)了組件的基本功能,抽象裝飾者定義了裝飾者的基本功能,具體裝飾者實(shí)現(xiàn)了裝飾者的基本功能,并且可以添加額外的功能。
裝飾者模式的優(yōu)點(diǎn)是可以動(dòng)態(tài)地添加或刪除對(duì)象的功能,而不需要修改現(xiàn)有的代碼。它還可以避免使用子類來(lái)擴(kuò)展對(duì)象的功能,從而減少類的數(shù)量。缺點(diǎn)是裝飾者模式會(huì)增加許多小對(duì)象,從而增加系統(tǒng)的復(fù)雜性。
2、裝飾者模式的優(yōu)缺點(diǎn)
裝飾者模式的優(yōu)點(diǎn)包括:
-
可以動(dòng)態(tài)地添加或刪除對(duì)象的功能,而不需要修改現(xiàn)有的代碼。
-
可以避免使用子類來(lái)擴(kuò)展對(duì)象的功能,從而減少類的數(shù)量。
-
可以將多個(gè)裝飾者組合起來(lái),實(shí)現(xiàn)更復(fù)雜的功能。
裝飾者模式的缺點(diǎn)包括:
-
裝飾者模式會(huì)增加許多小對(duì)象,從而增加系統(tǒng)的復(fù)雜性。
-
裝飾者模式可能會(huì)導(dǎo)致設(shè)計(jì)變得過(guò)于抽象,從而難以理解和維護(hù)。
-
裝飾者模式可能會(huì)影響程序的性能,因?yàn)槊總€(gè)裝飾者都會(huì)增加額外的處理時(shí)間。
3、裝飾者模式的應(yīng)用場(chǎng)景
裝飾者模式通常適用于以下場(chǎng)景:
-
在不影響現(xiàn)有對(duì)象結(jié)構(gòu)的情況下,動(dòng)態(tài)地添加額外的功能或行為。
-
需要擴(kuò)展一個(gè)類的功能,但是使用繼承會(huì)導(dǎo)致類的數(shù)量增加,且不利于維護(hù)。
-
需要在不修改代碼的情況下,對(duì)對(duì)象的某些功能進(jìn)行組合或移除。
-
需要對(duì)一個(gè)對(duì)象的功能進(jìn)行多次擴(kuò)展或組合,而不是一次性地進(jìn)行全部擴(kuò)展或組合。
-
需要在運(yùn)行時(shí)動(dòng)態(tài)地添加或刪除對(duì)象的功能。
-
需要在不破壞封裝性的前提下,對(duì)對(duì)象的功能進(jìn)行擴(kuò)展或修改。
-
需要對(duì)對(duì)象的功能進(jìn)行動(dòng)態(tài)排序或過(guò)濾。
-
需要對(duì)對(duì)象的功能進(jìn)行動(dòng)態(tài)配置或組合。
總之,裝飾者模式適用于需要?jiǎng)討B(tài)地添加或刪除對(duì)象的功能,同時(shí)又不希望對(duì)現(xiàn)有對(duì)象結(jié)構(gòu)進(jìn)行修改的場(chǎng)景。
4、裝飾者模式的結(jié)構(gòu)
裝飾者模式的結(jié)構(gòu)包括以下組件:
-
抽象組件(Component):定義了組件的接口,可以是抽象類或接口。
-
具體組件(Concrete Component):實(shí)現(xiàn)了抽象組件的接口,提供了基本的功能。
-
抽象裝飾者(Decorator):定義了裝飾者的接口,包含一個(gè)指向抽象組件的引用。
-
具體裝飾者(Concrete Decorator):實(shí)現(xiàn)了抽象裝飾者的接口,對(duì)抽象組件添加了新的功能。
裝飾者模式使用組合而非繼承的方式,動(dòng)態(tài)地將責(zé)任附加到對(duì)象上,從而實(shí)現(xiàn)了動(dòng)態(tài)地?cái)U(kuò)展對(duì)象的功能。它可以在不修改現(xiàn)有代碼的情況下,動(dòng)態(tài)地添加或刪除對(duì)象的功能,同時(shí)避免了使用子類來(lái)擴(kuò)展對(duì)象的功能,從而減少了類的數(shù)量。
5、裝飾者模式的代碼案例
假設(shè)有一個(gè)飲料類(Beverage),它有一個(gè)描述(description)和一個(gè)計(jì)算價(jià)格(cost)的方法?,F(xiàn)在需要給這個(gè)飲料類添加一些調(diào)料(Condiment),比如牛奶、摩卡等,這些調(diào)料也有自己的描述和價(jià)格。使用裝飾者模式,可以動(dòng)態(tài)地添加或刪除調(diào)料,而不需要修改飲料類的代碼。
首先,我們定義一個(gè)飲料類Beverage,它是一個(gè)抽象類,包含描述和計(jì)算價(jià)格兩個(gè)方法:
package com.pany.camp.design.principle.decorators;
/**
*
* @description: 抽象類
* @copyright: @Copyright (c) 2022
* @company: Aiocloud
* @author: pany
* @version: 1.0.0
* @createTime: 2023-06-27 20:37
*/
public abstract class Beverage {
String description = "Unknown Beverage";
public String getDescription() {
return description;
}
public abstract double cost();
}
然后,我們定義一個(gè)具體的飲料類Espresso,它繼承自Beverage類,實(shí)現(xiàn)了cost方法和description屬性:
package com.pany.camp.design.principle.decorators;
/**
*
* @description: 抽象實(shí)現(xiàn)
* @copyright: @Copyright (c) 2022
* @company: Aiocloud
* @author: pany
* @version: 1.0.0
* @createTime: 2023-06-27 20:38
*/
public class Espresso extends Beverage {
public Espresso() {
description = "Espresso";
}
public double cost() {
return 1.99;
}
}
接下來(lái),我們定義一個(gè)抽象的調(diào)料類CondimentDecorator,它也是一個(gè)抽象類,繼承自Beverage類,包含一個(gè)抽象的getDescription方法:
package com.pany.camp.design.principle.decorators;
/**
*
* @description: 抽象的調(diào)料類
* @copyright: @Copyright (c) 2022
* @company: Aiocloud
* @author: pany
* @version: 1.0.0
* @createTime: 2023-06-27 20:38
*/
public abstract class CondimentDecorator extends Beverage {
public abstract String getDescription();
}
然后,我們定義一個(gè)具體的調(diào)料類Milk,它繼承自CondimentDecorator類,包含一個(gè)Beverage類型的成員變量和一個(gè)構(gòu)造方法,用于接收一個(gè)飲料對(duì)象,然后將其保存到成員變量中。getDescription方法會(huì)調(diào)用Beverage對(duì)象的getDescription方法,并在其后面添加", Milk"。cost方法會(huì)調(diào)用Beverage對(duì)象的cost方法,并加上0.10的價(jià)格:
package com.pany.camp.design.principle.decorators;
/**
*
* @description: 具體的調(diào)料類Milk
* @copyright: @Copyright (c) 2022
* @company: Aiocloud
* @author: pany
* @version: 1.0.0
* @createTime: 2023-06-27 20:39
*/
public class Milk extends CondimentDecorator {
Beverage beverage;
public Milk(Beverage beverage) {
this.beverage = beverage;
}
public String getDescription() {
return beverage.getDescription() + ", Milk";
}
public double cost() {
return beverage.cost() + 0.10;
}
}
類似地,我們定義另一個(gè)具體的調(diào)料類Mocha,它也繼承自CondimentDecorator類,包含一個(gè)Beverage類型的成員變量和一個(gè)構(gòu)造方法,用于接收一個(gè)飲料對(duì)象,然后將其保存到成員變量中。getDescription方法會(huì)調(diào)用Beverage對(duì)象的getDescription方法,并在其后面添加", Mocha"。cost方法會(huì)調(diào)用Beverage對(duì)象的cost方法,并加上0.20的價(jià)格:
package com.pany.camp.design.principle.decorators;
/**
*
* @description: 具體的調(diào)料類Mocha
* @copyright: @Copyright (c) 2022
* @company: Aiocloud
* @author: pany
* @version: 1.0.0
* @createTime: 2023-06-27 20:40
*/
public class Mocha extends CondimentDecorator {
Beverage beverage;
public Mocha(Beverage beverage) {
this.beverage = beverage;
}
public String getDescription() {
return beverage.getDescription() + ", Mocha";
}
public double cost() {
return beverage.cost() + 0.20;
}
}
最后,我們可以使用如下的測(cè)試代碼來(lái)測(cè)試我們的裝飾者模式:
package com.pany.camp.design.principle.decorators;
/**
* @description: 客戶端
* @copyright: @Copyright (c) 2022
* @company: Aiocloud
* @author: pany
* @version: 1.0.0
* @createTime: 2023-06-27 20:40
*/
public class Client {
public static void main(String[] args) {
Beverage beverage = new Espresso();
System.out.println(beverage.getDescription() + " $" + beverage.cost());
beverage = new Milk(beverage);
System.out.println(beverage.getDescription() + " $" + beverage.cost());
beverage = new Mocha(beverage);
System.out.println(beverage.getDescription() + " $" + beverage.cost());
}
}
輸出結(jié)果為:
Espresso $1.99
Espresso, Milk $2.09
Espresso, Milk, Mocha $2.29
Process finished with exit code 0
可以看到,通過(guò)裝飾者模式,我們動(dòng)態(tài)地給飲料類添加了調(diào)料,而不需要修改飲料類的代碼。文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-503608.html
???? 本文由激流原創(chuàng),首發(fā)于CSDN博客,博客主頁(yè) https://blog.csdn.net/qq_37967783?spm=1010.2135.3001.5421
????喜歡的話記得點(diǎn)贊收藏啊文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-503608.html
到了這里,關(guān)于深入淺出設(shè)計(jì)模式 - 裝飾者模式的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!