(一)装饰模式(包装模式)
-
解决什么问题
-
向要对一个类进行多种组合方式的扩展,继承的话每种组合都是一个子类,而装饰者模式则可以每一个添加项是一个子类,根据需要对子类们所包含的功能进行随意的组合。
-
装饰品和被装饰者要继承同一个接口,不同的装饰品之间也要继承同一个抽象类,才能满足随意扩展的需求
-
比如说一杯奶茶(被装饰着),5种小料,包括奶盖,芋圆,珍珠,椰果和奥利奥(饰品),如果想要喝到不同种类组合的奶茶(不同结果类),且在小料种类增加时不更改原有菜单(原有代码)怎么办?
如果将组合列举出来(普通继承),将会有上百种组合(全部列出来会有几百个类);但如果我们可以以小料为单位(每一个装饰品实现一个装饰类,且全部与被装饰者继承同一个类),奶茶作为成员变量,需要什么小料就加什么小料就可以了(将原有类传进去,并在此基础上添加新功能)
最终呈现的是一个链式的,递进的对对象的封装。
2. 结构
3. 实现代码
//抽象构件
public interface Beverage {
int price();
String describe();
}
//具体构件
public class MilkTea implements Beverage {
@Override
public int price() {
return 10;
}
@Override
public String describe() {
return "奶茶";
}
}
//抽象装饰
public abstract class Flavour implements Beverage {
private Beverage baseDrink;
public Beverage getBaseDrink() {
return baseDrink;
}
public void setBaseDrink(Beverage baseDrink) {
this.baseDrink = baseDrink;
}
}
//具体装饰1
public class CheeseDrink extends Flavour {
public CheeseDrink(Beverage beverage){
setBaseDrink(beverage);
}
@Override
public String describe() {
return getBaseDrink().describe()+" +芝士奶盖";
}
@Override
public int price() {
return getBaseDrink().price()+3;
}
}
//具体装饰2
public class OreoDrink extends Flavour {
public OreoDrink(Beverage beverage){
setBaseDrink(beverage);
}
@Override
public String describe() {
return getBaseDrink().describe()+" +奥利奥碎";
}
@Override
public int price() {
return getBaseDrink().price()+7;
}
}
//具体装饰3
public class PearlDrink extends Flavour {
public PearlDrink(Beverage b){
this.setBaseDrink(b);
}
@Override
public String describe() {
return getBaseDrink().describe()+" +珍珠";
}
@Override
public int price() {
return getBaseDrink().price()+5;
}
}
public static void main(String[] args){
Beverage a = new MilkTea();
System.out.println(a.describe());
System.out.println(a.price());
Flavour b = new PearlDrink(a);
System.out.println(b.describe());
System.out.println(b.price());
Flavour c = new CheeseDrink(b);
System.out.println(c.describe());
System.out.println(c.price());
Flavour d = new OreoDrink(b);
System.out.println(d.describe());
System.out.println(d.price());
}
输出:
4. 缺点
-
每一种饰品单独声明一个类,当饰品种类特别多时,装饰者类就会特别多