橋接模式與裝飾模式的對比

憑欄觀雨_遠發表於2017-06-21

使用裝飾模式進行系統設計時將產生很多小物件,這些物件的區別在於它們之間相互連線的方式有所不同,而不是它們的類或者屬性值有所不同,同時還將產生很多具體裝飾類。這些裝飾類和小物件的產生將增加系統的複雜度,加大學習與理解的難度。

這種比繼承更加靈活機動的特性,也同時意味著裝飾模式比繼承更加易於出錯,排錯也很困難,對於多次裝飾的物件,除錯時尋找錯誤可能需要逐級排查,較為煩瑣。

裝飾模式就像中秋節包裝過的月餅一樣,可以包多層,每一層可以使用不同的包裝紙來包裝。

橋接模式與裝飾模式

兩個模式都是為了解決子類過多問題, 但他們的誘因不同:
1.橋接模式物件自身有 沿著多個維度變化的趨勢 , 本身不穩定;
2.裝飾者模式物件自身非常穩定, 只是為了增加新功能/增強原功能。
類圖
橋接模式
這裡寫圖片描述

裝飾模式
這裡寫圖片描述
示例程式碼:

//抽象類:建築
public abstract class Building {
    protected Paint paint;
    public Building(Paint paint) {
        this.paint = paint;
    }
    public abstract void decorate();
}
//介面:油漆
public interface Paint {
    void decorateImpl();
}
//教學樓
public class TeachingBuilding extends Building {
    public TeachingBuilding(Paint paint) {
        super(paint);
    }

    @Override
    public void decorate() {
        System.out.print("普通的教學樓");
        paint.decorateImpl();
    }
}
//實驗樓
public class LaboratoryBuilding extends Building {
    public LaboratoryBuilding(Paint paint) {
        super(paint);
    }

    @Override
    public void decorate() {
        System.out.print("普通的實驗樓");
        paint.decorateImpl();
    }
}
public class RedPaint implements Paint {
    @Override
    public void decorateImpl() {
        System.out.println("被紅色油漆裝飾過。");
    }
}
public class GreenPaint  implements Paint {
    @Override
    public void decorateImpl() {
        System.out.println("被綠色油漆裝飾過。");
    }
}
public class BulePaint implements Paint {
    @Override
    public void decorateImpl() {
        System.out.println("被藍色油漆裝飾過。");
    }
}
public class BridgePatternDemo {
    public static void main(String[] args) {
        //普通的教學樓被紅色油漆裝飾。
        Building redTeachingBuilding=new TeachingBuilding(new RedPaint());
        redTeachingBuilding.decorate();
        //普通的教學樓被綠色油漆裝飾。
        Building greenTeachingBuilding1=new TeachingBuilding(new GreenPaint());
        greenTeachingBuilding1.decorate();
        //普通的實驗樓被紅色油漆裝飾。
        Building redLaboratoryBuilding=new LaboratoryBuilding(new RedPaint());
        redLaboratoryBuilding.decorate();
        //普通的實驗樓被綠色油漆裝飾。
        Building greenLaboratoryBuilding=new LaboratoryBuilding(new GreenPaint());
        greenLaboratoryBuilding.decorate();
        //普通的實驗樓被藍色油漆裝飾。
        Building blueLaboratoryBuilding=new LaboratoryBuilding(new BulePaint());
        blueLaboratoryBuilding.decorate();
    }
}

執行結果:

普通的教學樓被紅色油漆裝飾過。
普通的教學樓被綠色油漆裝飾過。
普通的實驗樓被紅色油漆裝飾過。
普通的實驗樓被綠色油漆裝飾過。
普通的實驗樓被藍色油漆裝飾過。

裝飾模式

簡明的說:
是你還有你,一切拜託你。

裝飾模式就像中秋節包裝過的月餅一樣,可以
包多層,每一層可以使用不同的包裝紙來包裝
再放一遍類圖
這裡寫圖片描述
示例程式碼:

//介面:建築
public interface Building {
    void decorate();
}
//抽象類:油漆
public abstract class Paint implements Building {
    protected Building building;

    public Paint(Building building) {
        this.building = building;
    }
    public void decorate(){
        building.decorate();
    }
}
//實驗樓
public class LaboratoryBuilding implements Building{
    @Override
    public void decorate() {
        System.out.print("普通的實驗樓");
    }
}
 //教學樓
public class TeachingBuilding implements Building {
    @Override
    public void decorate() {
        System.out.print("普通的教學樓");
    }
}
//紅色油漆
public class RedPaint extends Paint {
    public RedPaint(Building building) {
        super(building);
    }

    @Override
    public void decorate() {
        building.decorate();
        decorateByRedPaint();
    }
    public void decorateByRedPaint(){
        System.out.print("被紅色油漆裝飾過");
    }
}
//綠色油漆
public class GreenPaint extends Paint {
    public GreenPaint(Building building) {
        super(building);
    }

    @Override
    public void decorate() {
        building.decorate();
        decorateByGreenPaint();
    }
    public void decorateByGreenPaint(){
        System.out.print("被綠色油漆裝飾過");
    }
}
//藍色油漆
public class BulePaint extends Paint {
    public BulePaint(Building building) {
        super(building);
    }

    @Override
    public void decorate() {
        building.decorate();
        decorateByBluePaint();
    }
    public void decorateByBluePaint(){
        System.out.print("被藍色油漆裝飾過");
    }
}
public class  DecoratorPatternDemo {
    public static void main(String[] args) {

        System.out.println("\n-*-被紅色油漆裝飾過的普通的教學樓-*-");
        Building redTeachingBuilding=new RedPaint(new TeachingBuilding());
        redTeachingBuilding.decorate();
        System.out.println("\n-*-被綠色油漆裝飾過的普通的教學樓-*-");
        Building greenTeachingBuilding=new GreenPaint(new TeachingBuilding());
        greenTeachingBuilding.decorate();
        System.out.println("\n-*-被紅色油漆裝飾過的普通的實驗樓-*-");
        Building redLaboratoryBuilding=new RedPaint(new LaboratoryBuilding());
        redLaboratoryBuilding.decorate();
        System.out.println("\n-*-被綠色油漆裝飾過的普通的實驗樓-*-");
        Building greenLaboratoryBuilding=new GreenPaint(new LaboratoryBuilding());
        greenLaboratoryBuilding.decorate();
        System.out.println("\n-*-被紅色和綠色油漆裝飾過的普通的實驗樓-*-");
        Building building=new GreenPaint(new RedPaint(new LaboratoryBuilding()));
        building.decorate();
        System.out.println("\n-*-被紅色和綠色和藍色油漆裝飾過的普通的實驗樓-*-");
        Building building1=new BulePaint(new GreenPaint(new RedPaint(new LaboratoryBuilding())));
        building1.decorate();
    }
}

執行結果:

-*-被紅色油漆裝飾過的普通的教學樓-*-
普通的教學樓被紅色油漆裝飾過
-*-被綠色油漆裝飾過的普通的教學樓-*-
普通的教學樓被綠色油漆裝飾過
-*-被紅色油漆裝飾過的普通的實驗樓-*-
普通的實驗樓被紅色油漆裝飾過
-*-被綠色油漆裝飾過的普通的實驗樓-*-
普通的實驗樓被綠色油漆裝飾過
-*-被紅色和綠色油漆裝飾過的普通的實驗樓-*-
普通的實驗樓被紅色油漆裝飾過被綠色油漆裝飾過
-*-被紅色和綠色和藍色油漆裝飾過的普通的實驗樓-*-
普通的實驗樓被紅色油漆裝飾過被綠色油漆裝飾過被藍色油漆裝飾過

相關文章