它主要是解決:java
「過分地使用了繼承來擴展對象的功能」,因爲繼承爲類型引入的靜態特質,使得這種擴展方式缺少靈活性;
而且隨着子類的增多(擴展功能的增多),各類子類的組合(擴展功能的組合)會致使更多子類的膨脹(多繼承)。
繼承爲類型引入的靜態特質的意思是說以繼承的方式使某一類型要得到功能是在編譯時。
所謂靜態,是指在編譯時;動態,是指在運行時。markdown
示例類圖:
app
示例代碼:ide
// Component
public interface Sender {
public void send(String msg);
}
// ConcreteComponent
public class MailSender implements Sender {
@Override
public void send(String msg) {
System.out.println("MailSender send : " + msg);
}
}
public class SmsSender implements Sender {
@Override
public void send(String msg) {
System.out.println("SmsSender send : " + msg);
}
}
// Decorator接口或者抽象類
public abstract class DecoratorSender implements Sender {
protected Sender sender;
public DecoratorSender(Sender sender) {
this.sender = sender;
}
@Override
public void send(String msg) {
sender.send(msg);
}
}
// 具體實現Decorator接口或者繼承抽象類的類
public class DecoratorEncodeSender extends DecoratorSender {
public DecoratorEncodeSender(Sender sender) {
super(sender);
}
@Override
public void send(String msg) {
super.send(encode(msg));
}
// 爲sender對象發送的msg特殊編碼
private String encode(String msg) {
System.out.println("編碼處理...");
return "###" + msg + "$$$";
}
}
// 測試
public class DecoratorTest {
public static void main(String[] args) {
Sender sender = new MailSender();
DecoratorSender decoratorSender = new DecoratorEncodeSender(sender);
decoratorSender.send("郵箱信息...");
new DecoratorEncodeSender(new SmsSender()).send("短信信息..");
sender = new DecoratorEncodeSender(new SmsSender());
}
}
Decorator裝飾模式的幾點要點:函數
經過採用組合、而非繼承的手法,Decorator模式實現了在運行時動態的擴展對象功能的能力,
並且能夠根據須要擴展多個功能。避免了單獨使用繼承帶來的「靈活性差」和「多子類衍生問題」。測試
Component類在Decorator模式中充當抽象接口的角色,不該該去實現具體的行爲。
並且Decorator類對於Component類應該透明——換言之Component類無需知道Decorator類,
Decorator類是從外部來擴展Component類的功能。this
Decorator類在接口上表現爲is-a Component的繼承關係,即Decorator類繼承了Component類所具備的接口。
但在實現上又表現爲has-a Component的組合關係,即Decorator類又使用了另一個Component類。
咱們可使用一個或多個Decorator對象來「裝飾」一個Component對象,且裝飾後的對象仍然是一個Component對象。編碼
在這裏我想談一下個人理解:當咱們實例化一個Component對象後,要給這個對象擴展功能,
這時咱們把這個Component對象看成參數傳給Decorator的子類的構造函數——也就是擴展方法的功能類。
對於引用類型傳參時,實際上只是傳遞對象的地址,這樣,在功能擴展是,操做的應該是同一個對象。spa
Decorator模式並不是解決「多子類衍生的多繼承」問題,Decorator模式應用的要點在於解決「主體類在多個方向上的擴展功能」——是爲「裝飾」的含義。
Decorator是在運行時對功能進行組合。code
須要擴展一個類的功能。
動態的爲一個對象增長功能,並且還能動態撤銷。(繼承不能作到這一點,繼承的功能是靜態的,不能動態增刪)