JAVA實現裝飾模式
環境:汽車4s店汽車銷售,出售奧迪A1,A4,A6。可裝飾的元件有倒車雷達,真皮座椅,GPS定位。有一輛裸車,要實現對裸車的裝飾
分析:買車的人需求各不一樣,有的人要奧迪A1裝有雷達、GPS,有的人要奧迪A4裝有真皮座椅、GPS等等。如果你把所有的可能情況都例舉出來,就會出現“類爆炸”的現象,顯然這是不合理的。
問題:動態的給一個物件新增一些功能擴充套件
解決方案:裝飾模式
角色:裝飾者
被裝飾者
Car.java
public abstract class Car {
protected int cost;
protected String description;
public abstract String getDescription();
public abstract int getCost();
}
A1Car.java
public class A1Car extends Car{
public A1Car()
{
cost = 100000;
description = "Audi A1 Car";
}
@Override
public int getCost() {
return cost;
}
@Override
public String getDescription() {
return description;
}
}
A4Car.java
public class A4Car extends Car{
public A4Car()
{
cost = 120000;
description = "Audi A4 Car";
}
@Override
public int getCost() {
return cost;
}
@Override
public String getDescription() {
return description;
}
}
Decorator.java
public class Decorator extends Car{
protected Car c;
protected int decoratorcost;
protected String decoratordescription;
public void setCar(Car a){
c = a;
}
@Override
public int getCost() {
return decoratorcost+c.getCost();
}
@Override
public String getDescription() {
return decoratordescription+c.getDescription();
}
}
GPS.java
public class Gps extends Decorator{
public Gps(){
decoratorcost=500;
decoratordescription="with GPS";
}
}
Radar.java
public class Radar extends Decorator{
public Radar(){
decoratorcost=1500;
decoratordescription="with Radar";
}
}
Test.java
public class Test {
public static void main(String[] args) {
//給奧迪A1裝配GPS
Car a1 = new A1Car();
Decorator decorator = new Gps();
decorator.setCar(a1);
System.out.println(a1.getDescription()+"的價格是"+a1.getCost());
System.out.println(decorator.getDescription()+"的價格是"+decorator.getCost());
//想再給A1裝配Radar,由於裝飾者與被裝飾者具有相同的型別,我們可以用裝飾後的物件代替原來的物件
Decorator decorator2 = new Radar();
decorator2.setCar(decorator);
System.out.println(decorator2.getDescription()+"的價格是"+decorator2.getCost());
}
}
執行結果
Audi A1 Car的價格是100000
with GPS Audi A1 Car的價格是100500
with Radar with GPS Audi A1 Car的價格是102000
在Java I/O庫中輸入輸出流的設計模式就使用了裝飾模式
專案中,我們經常這樣寫
FileReader fr = new FileReader("d:\\myDoc\\test.txt");
BufferedReader br = new BufferedReader(fr);//這裡接收一個Reader型別引數
BufferedReader相當於裝飾者,而Reader及其子類都可以作為被裝飾者