簡述
運行時,為原物件拓展新的行為,
相較于傳統的繼承來拓展新的行為,裝飾器模式更為的靈活多變,當然實作起來也更為復雜,
話不多說,看個優化案例吧,
優化案例
最初版v0
現有系統中有設定視窗Style的模塊,現在想增加一個圓角的樣式,以下是現有模塊的代碼,
class Style {
public void style() {
System.out.println("設定Order");
}
}
第一種傳統的修改方式,
class Style {
public void style() {
System.out.println("設定Order");
System.out.println("設定Radius");
}
}
雖然代碼簡單,但細想一下,如果我們日后仍然需要單獨設定Order的樣式怎么辦,現在的代碼實作已經無法滿足了不是?
為此,我們可能會想到另一種方案,使用繼承,
class BaseStyle {
public void style() {
System.out.println("設定Order");
}
}
class Radius extends BaseStyle {
public void style() {
super.style();
System.out.println("設定Radius");
}
}
確實,如果不在意類的命名的話,目前來看這確實是個好的選擇,請注意,只是目前來看,設計不只著眼與當前,而是需要放眼未來,什么意思呢?比如,當未來需要添加一個Color樣式的時候怎么辦,有人可能認為添加再添加一個BassStyle類的子類Color就好了;如果客戶就只要一個單獨的Color樣式呢,或者說需要一個可以設定Radius和Color的樣式,再超前一些,客戶如果想要的是增加一個樣式,且可以與現有的任何一種或多種樣式隨意組合呢?又該怎么辦?傳統的繼承已經搞不了了呀,
別慌,最后這一種需求正好就是使用裝飾器模式的目的,我們來看看改進后的案例吧,
修改版v1
使用裝飾器模式優化上述需求,使得任意樣式間可以任意組合,這種任意組合包括任意種類和數量,
public interface Style {
void style();
}
public class Order implements Style {
@Override
public void style() {
System.out.println("設定Order");
}
}
public class Radius implements Style {
@Override
public void style() {
System.out.println("設定Radius");
}
}
public class Color implements Style {
@Override
public void style() {
System.out.println("設定Color");
}
}
public class OrderDecorator implements Style {
private Style style;
public OrderDecorator(Style target) {
this.style = target;
}
@Override
public void style() {
style.style();
decorator();
}
private void decorator() {
System.out.println("設定Order");
}
}
public class RadiusDecorator implements Style {
private Style style;
public RadiusDecorator(Style target) {
this.style = target;
}
@Override
public void style() {
style.style();
decorator();
}
private void decorator() {
System.out.println("設定Radius");
}
}
public class ColorDecorator implements Style {
private Style style;
public ColorDecorator(Style target) {
this.style = target;
}
@Override
public void style() {
style.style();
decorator();
}
private void decorator() {
System.out.println("設定Color");
}
}
定義三個裝飾器類:OrderDecorator, RadiusDecorator, ColorDecorator分別實作Style介面,定義decorator方法用(動態拓展的核心方法之一),呼叫完``target的style方法后呼叫decorator`方法實作功能的動態拓展,接著,看看客戶端如何使用,
public class Client {
public static void main(String[] args) {
Style style = new Order();
Style style1 = new ColorDecorator(style);
Style style2 = new RadiusDecorator(style1);
style2.style();
}
}
輸出結果:
設定Order
設定Color
設定Radius
修改版v2
上述優化可以看到一些重復冗余的代碼,還有再次優化的空間,以下是實作樣例,
public interface Style {
void style();
}
public class Order implements Style {
@Override
public void style() {
System.out.println("設定Order");
}
}
public class Radius implements Style {
@Override
public void style() {
System.out.println("設定Radius");
}
}
public class Color implements Style {
@Override
public void style() {
System.out.println("設定Color");
}
}
public abstract class StyleDecorator implements Style { // 抽出共通新建裝飾類的高層抽象類
protected Style style;
public StyleDecorator(Style target) {
this.style = target;
}
@Override
public void style() { // style設定
style.style();
decorator();
}
protected abstract void decorator(); // 裝飾方法
}
public class OrderDecorator extends StyleDecorator {
public OrderDecorator(Style target) {
super(target);
}
@Override
protected void decorator() {
System.out.println("設定Order");
}
}
public class RadiusDecorator extends StyleDecorator {
public RadiusDecorator(Style target) {
super(target);
}
@Override
protected void decorator() {
System.out.println("設定Radius");
}
}
public class ColorDecorator extends StyleDecorator {
public ColorDecorator(Style target) {
super(target);
}
@Override
protected void decorator() {
System.out.println("設定Color");
}
}
客戶端的使用和輸出結果還是和v1一樣,
public class Client {
public static void main(String[] args) {
Style style = new Order();
Style style1 = new ColorDecorator(style);
Style style2 = new RadiusDecorator(style1);
style2.style();
}
}
輸出結果:
設定Order
設定Color
設定Radius
新建高層抽象類,講冗余的方法屬性都打包到抽象類中,減少重復的代碼,
這個應該屬于題外話了,可以見得設計模式的實作方式是多種多樣的,不要過度拘泥于模板,只要能達成目的,想怎么設計就可以怎么設計,
修改版v1和v2都是裝飾器模式,實際開發根據需求斟酌即可,
總結
優點
- 開發時可以自由組合各種各樣的功能,
- 新增的功能對于現有功能沒有任何的影響,
缺點
- 增加系統的復雜度,
- 對于開發人員的技術要求提高,
應用場景
- 需要靈活組合功能的場合,
- 限制繼承,但又想拓展類的功能的場合,
本文來自博客園,作者:spoonb,轉載請注明原文鏈接:https://www.cnblogs.com/spoonb/p/16731658.html
個人主頁:blogcafe.cn 比博客園更新速度更快,歡迎大家的光顧
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/528717.html
標籤:Java
上一篇:day12-Servlet02
