必威电竞|足球世界杯竞猜平台

裝飾模式
來(lái)源:互聯(lián)網(wǎng)

裝飾模式是一種設(shè)計(jì)模式,在不需要更改原有類(lèi)文件和使用繼承的情況下,能夠動(dòng)態(tài)地?cái)U(kuò)展一個(gè)對(duì)象的功能。這種模式通過(guò)創(chuàng)建一個(gè)包裝對(duì)象,即裝飾者,來(lái)封裝實(shí)際的對(duì)象。

定義

裝飾模式,又稱(chēng)Decorator Pattern,是23種設(shè)計(jì)模式之一。它允許在運(yùn)行時(shí)動(dòng)態(tài)地向一個(gè)對(duì)象添加新的行為,而不必修改原有的類(lèi)。裝飾模式通過(guò)創(chuàng)建一個(gè)包裝對(duì)象,即裝飾者,來(lái)封裝實(shí)際的對(duì)象。

特點(diǎn)

裝飾對(duì)象與真實(shí)對(duì)象具有相同的接口,這使得客戶(hù)端對(duì)象能夠以與真實(shí)對(duì)象相同的方式與裝飾對(duì)象交互。

裝飾對(duì)象包含一個(gè)指向真實(shí)對(duì)象的引用。

裝飾對(duì)象接收來(lái)自客戶(hù)端的所有請(qǐng)求,并將其轉(zhuǎn)發(fā)給真實(shí)對(duì)象。

在轉(zhuǎn)發(fā)請(qǐng)求之前或之后,裝飾對(duì)象可以添加額外的功能,從而無(wú)需修改給定對(duì)象的結(jié)構(gòu)即可在運(yùn)行時(shí)添加功能。在面向?qū)ο蟮脑O(shè)計(jì)中,通常通過(guò)繼承來(lái)實(shí)現(xiàn)對(duì)給定類(lèi)的功能擴(kuò)展。

適用性

裝飾模式適用于以下場(chǎng)景:

1. 需要擴(kuò)展一個(gè)類(lèi)的功能,或?yàn)槠涮砑痈郊勇氊?zé)。

2. 動(dòng)態(tài)地為一個(gè)對(duì)象添加功能,且這些功能可以隨時(shí)取消。

3. 增加由基本功能組成的大量功能,使繼承關(guān)系變得不切實(shí)際。

4. 當(dāng)無(wú)法通過(guò)子類(lèi)化來(lái)擴(kuò)展時(shí),如當(dāng)類(lèi)定義被隱藏,或類(lèi)定義不能用于生成子類(lèi)時(shí)。

優(yōu)點(diǎn)

裝飾模式提供了比繼承更靈活的方式來(lái)擴(kuò)展對(duì)象的功能。

通過(guò)使用不同的具體裝飾類(lèi)及其組合,設(shè)計(jì)師可以創(chuàng)造多種不同的行為組合。

缺點(diǎn)

裝飾模式的靈活性也帶來(lái)了更高的復(fù)雜度。

過(guò)度使用裝飾模式可能導(dǎo)致程序結(jié)構(gòu)變得復(fù)雜。

設(shè)計(jì)原則

應(yīng)優(yōu)先考慮組合而非繼承。

類(lèi)的設(shè)計(jì)應(yīng)該對(duì)擴(kuò)展開(kāi)放,對(duì)修改封閉。

模式簡(jiǎn)化

若只有一個(gè)具體的Component類(lèi),則讓Decorator繼承該類(lèi)。

若只有一個(gè)具體的Decorator類(lèi),則可以將Decorator和混凝土 Decorator合并。

相關(guān)區(qū)別

新職責(zé)方面,適配器模式也能在轉(zhuǎn)換時(shí)增加新職責(zé),但其主要目的是轉(zhuǎn)換接口,而裝飾模式的主要目的是為被裝飾者增加新職責(zé)。

接口方面,適配器模式使用新接口調(diào)用原接口,原接口對(duì)于新系統(tǒng)來(lái)說(shuō)是不可見(jiàn)的;而裝飾模式保持原接口不變,系統(tǒng)通過(guò)原接口使用裝飾對(duì)象。

包裹對(duì)象方面,適配器了解被適配者的細(xì)節(jié),而裝飾者只知其接口,具體類(lèi)型則在運(yùn)行時(shí)確定。

實(shí)際使用

Java IO流是裝飾模式的一個(gè)典型例子。

代碼示例

在裝飾模式中,涉及的角色包括:

抽象構(gòu)件(Component)角色:定義一個(gè)接口,規(guī)范準(zhǔn)備接收附加責(zé)任的對(duì)象。

具體構(gòu)件(混凝土 Component)角色:定義一個(gè)將要接收附加責(zé)任的類(lèi)。

裝飾(Decorator)角色:持有構(gòu)件(Component)對(duì)象的實(shí)例,并實(shí)現(xiàn)與抽象構(gòu)件接口一致的接口。

具體裝飾(Concrete Decorator)角色:負(fù)責(zé)為構(gòu)件對(duì)象添加附加的責(zé)任。

以下示例展示了如何使用裝飾模式來(lái)擴(kuò)展現(xiàn)有類(lèi)的功能。其中,ThirdParty.Java表示一個(gè)已有的或第三方的功能,由于某些原因無(wú)法直接修改,它提供了一個(gè)sayMsg()方法。現(xiàn)在我們要在sayMsg()方法中添加一些額外的信息,因此我們編寫(xiě)了一個(gè)Decorator.java類(lèi)。MailTest.java是客戶(hù)端測(cè)試程序。

```java

// IthirdParty.Java--抽象接口類(lèi)

package decorator.saystr;

public 接口 IThirdParty {

public String sayMsg();

}

// ThirdParty.Java--具體類(lèi)

public class ThirdParty implements IThirdParty {

public String sayMsg() {

return "hello";

}

}

// Decorator1.java 具體裝飾類(lèi)1

package decorator.saystr;

public class Decorator1 implements IThirdParty {

private IThirdParty thirdParty;

public Decorator1(IThirdParty thirdParty) {

this.thirdParty = thirdParty;

}

public String sayMsg() {

return "##1" + thirdParty.sayMsg() + "##1";

}

}

// Decorator2.java 具體裝飾類(lèi)2

package decorator.saystr;

public class Decorator2 implements IThirdParty {

private IThirdParty thirdParty;

public Decorator2(IThirdParty thirdParty) {

this.thirdParty = thirdParty;

}

public String sayMsg() {

return "##2" + thirdParty.sayMsg() + "##2";

}

}

// MailTest.java

package decorator.saystr;

public class MailTest {

public static void main(String[] args) {

IThirdParty thirdPartyOne = new ThirdParty();

IThirdParty decorator1 = new Decorator1(thirdPartyOne);

IThirdParty decorator2 = new Decorator2(decorator1);

System.out.println(decorator2.sayMsg());

}

}

```

執(zhí)行結(jié)果為:`##2##1hello##1##2`

參考資料 >

設(shè)計(jì)模式之裝飾模式(Decorator).博客園.2024-11-04

23種設(shè)計(jì)模式之裝飾者(Decorator)模式.掘金開(kāi)發(fā)者社區(qū).2024-11-04

3.裝飾模式.Graphic Design Patterns.2024-11-04

生活家百科家居網(wǎng)