1. 程式人生 > >【程式設計素質】設計模式-裝飾模式(Decorator,包裝模式Wrapper)

【程式設計素質】設計模式-裝飾模式(Decorator,包裝模式Wrapper)

1,概念

是動態地將責任附加到物件上,若要擴充套件功能,裝飾者提供了比繼承更有彈性的替代方案。

是以對客戶端透明的方式擴充套件物件的功能,換句話說,客戶端不會察覺到裝飾前與裝飾後有什麼不同。

在不修改底層程式碼情況下,給物件賦予新的職責。

2,場景(處於安全目的,保護被訪問者)

現在有一個物件,我們想給他增加方法或者屬性,怎麼去做,並且可以隨意修改增加方法和屬性的順序。

I/O、過濾器。

3,注意

①裝飾者和被裝飾物件有相同的超型別。 因為裝飾者必須能取代被裝飾者。 ②可以有多個裝飾者。 ③裝飾模式輸出的過程就像拆包,拆開每一個裝飾者內容。

4,優缺點

1)優

讓演算法的變化獨立於使用演算法的客戶。

2)缺

造成設計中有大量的小類。 裝飾者在例項化元件時,將增加程式碼複雜度。(不只需要例項化元件,還要把此元件包裝進裝飾者中)。

5,經典用例:

java.io類: 這裡寫圖片描述 例子:用BufferedReader修飾InputStreamReader物件:

BufferedReader input = new BufferedReader(new InputStreamReader(System.in));

6,實現

由4部分組成: ①抽象介面 ②具體元件(要接收附加責任的類) ③抽象裝飾者 ④具體裝飾者(給介面物件新增附加責任) 這裡寫圖片描述

package decorator;

public
class Main { public static void main(String args[]){ Beverage beverage = new Espresso(); System.out.println("訂一杯Espresso,不要調料"); System.out.println(beverage.getDescription() + "$" + beverage.cost()); System.out.println("-------------"); System.out
.println("訂一杯HouseBlend"); Beverage beverage2 = new HouseBlend(); System.out.println("加調料:Mocha裝飾它"); beverage2 = new Mocha(beverage2); System.out.println("加調料:Mocha裝飾它"); beverage2 = new Mocha(beverage2); System.out.println("加調料:Whip裝飾它"); beverage2 = new Whip(beverage2); System.out.println(beverage2.getDescription() + "$" + beverage2.cost()); } }
package decorator;
/**
 * 抽象元件
 * 飲料超類:介面(也可以用抽象類替代)
 * @author luo
 *
 */
public interface Beverage {

    public double cost();
    public String getDescription();

}
package decorator;

/**
 * 抽象裝飾者
 * 調料類:抽象類
 * @author luo
 *
 */
public abstract class CondimentDeccorator implements Beverage{
    @Override
    public abstract String getDescription();
}
package decorator;

/**
 * 具體元件
 * 濃縮咖啡類
 * 
 * @author luo
 *
 */
public class Espresso implements Beverage {

    private String description = "Espresso";
    private double price = 1.2;

    @Override
    public double cost() {

        System.out.println("Espresso價格,1.2");
        return price;
    }

    @Override
    public String getDescription() {

        return description;
    }

}
package decorator;
/**
 * 具體元件
 * 一種飲料
 * @author luo
 *
 */
public class HouseBlend  implements Beverage {

    private String description = "HouseBlend Coffee";
    private double price = 1.5;

    @Override
    public double cost() {

        System.out.println("HouseBlend價格,1.5");
        return price;
    }

    @Override
    public String getDescription() {

        return description;
    }
}
package decorator;
/**
 * 摩卡類
 */
public class Mocha extends CondimentDeccorator{

    Beverage beverage;

    public Mocha(Beverage beverage){
        this.beverage = beverage;
    }

    @Override
    public double cost() {

        System.out.println("Mocha調料,0.2");
        return .20 + beverage.cost();
    }

    @Override
    public String getDescription() {

        return beverage.getDescription() + ", Mocha";
    }
}
package decorator;

public class Whip extends CondimentDeccorator{

    Beverage beverage;

    public Whip(Beverage beverage){
        this.beverage = beverage;
    }

    @Override
    public double cost() {

        System.out.println("Whip調料,0.2");
        return .20 + beverage.cost();
    }

    @Override
    public String getDescription() {

        return beverage.getDescription() + ", Whip";
    }
}