装饰器模式:
在不改变对象源代码的基础上(保持类方法签名完整性),进行动态的增加一些额外的功能。
应用实例:
1、孙悟空有 72 变,当他变成"庙宇"后,他的根本还是一只猴子,但是他又有了庙宇的功能。
2、不论一幅画有没有画框都可以挂在墙上,但是通常都是有画框的,并且实际上是画框被挂在墙上。
在挂在墙上之前,画可以被蒙上玻璃,装到框子里;这时画、玻璃和画框形成了一个物体。
优点:
装饰类和被装饰类可以独立发展,不会相互耦合,装饰模式是继承的一个替代模式,装饰模式可以动态扩展一个实现类的功能。
缺点:
多层装饰比较复杂。
使用场景:
1、扩展一个类的功能。
2、动态增加功能,动态撤销。
注意事项:
可代替继承。
步骤:
1、接口:抽象构件(被装饰者)
2、实现类:具体构件(具体被修饰者)
3、抽象类:抽象角色(装饰者)
4、子类:具体角色(具体装饰者:可以写多个)
例子:
使用装饰器模式实现火锅点餐。
解题思路:
1. 创建抽象构件:被装饰者锅底
2. 创建具体构件:具体被装饰者
3. 创建抽象角色:点餐类
4. 创建具体角色 :具体的食材
步骤一:
创建接口
接口:火锅底锅
public interface PotBottom {
String getName();
int getPrice();
}
步骤二:
创建实现接口的实体类。
实体类:菌汤类
public class MushroomSoup implements PotBottom {
@Override
public String getName() {
return "菌汤";
}
@Override
public int getPrice() {
return 520;
}
}
实体类:麻辣汤
public class SpicySoup implements PotBottom {
@Override
public String getName() {
return "辣汤";
}
@Override
public int getPrice() {
return 250;
}
}
步骤三:
创建实现了锅底接口的抽象装饰类。
抽象类:点菜类
//实现接口目的就是为了重写接口中的方法
//写成抽象类的目的是因为该类是纯粹概念性的类
//抽象装饰者
public abstract class Order implements PotBottom {
//接口做成员变量
private PotBottom pb;
public Order(PotBottom pb) {
super();
this.pb = pb;
}
@Override
public String getName() {
return pb.getName();
}
@Override
public int getPrice() {
return pb.getPrice();
}
}
步骤四:
具体装饰类:精品肥羊类
public class FineSheep extends Order {
public FineSheep(PotBottom pb) {
super(pb);
}
@Override
public String getName() {
return super.getName() + "精品肥羊";
}
@Override
public int getPrice() {
return super.getPrice() + 220;
}
}
具体装饰类:辣椒类
public class Pepper extends Order {
public Pepper(PotBottom pb) {
super(pb);
}
public String getName() {
return super.getName() + "这是辣椒,够你喝一壶";
}
@Override
public int getPrice() {
return super.getPrice() + 289;
}
}
最后一步:
测试
public class Test {
public static void main(String[] args) {
Order o1 = new Pepper(new MushroomSoup());
System.out.println(o1.getName() + "\n" + o1.getPrice());
Order o2 = new FineSheep(new Pepper(new MushroomSoup()));
System.out.println(o2.getName() + "\n" + o2.getPrice());
}
}