一、装饰者模式概述
装饰者模式使用组合的方法,可以在不修改底层代码的情况下为对象添加新的功能,
二、装饰者模式解决了什么问题
当一个基类的继承者众多且继承者们又有各自的特点并且需要互相组合使用时,这时我们应该使用装饰者模式.
三、装饰者模式思维图
四、装饰者模式的示例
创建一个基类
创建基类,装饰者和被装饰者都继承了他。(你也可以创建接口请根据实际需求确定)
package 设计模式.装饰者模式;
/*定义一个饮料的抽象类 Beverage决定了装饰者可装饰的类型*/
public abstract class Beverage {
/*为子类们提供几个复用的属性*/
String name;
double price;
int number;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
public int getNumber() {
return number;
}
public void setNumber(int number) {
this.number = number;
}
abstract double cost();
}
创建被装饰者
package 设计模式.装饰者模式;
/*创建一个被装饰者 咖啡类*/
public class coffee extends Beverage {
/*重写属性,数据安全*/
private String name;
private double price;
private int number;
public coffee(){
/*在父类中默认实现了set方法,为了代码复用*/
setName("咖啡");
setNumber(1);
setPrice(5.6);
}
/*提供计算价格的方法*/
@Override
double cost() {
return getNumber() * getPrice();
}
}
创建一个装饰者基类
装饰者基类继承了Beverage 拥有和被装饰者相同的方法属性,但是多出了Beverage 属性和属性的set方法,
package 设计模式.装饰者模式;
/*创建一个调料类 (装饰者类)*/
public abstract class Condiment extends Beverage{
/*装饰者核心在所在*/
Beverage beverage;
double cost() {
return (beverage.cost()) + (getPrice() * getNumber());
}
}
创建一个装饰者具体类
package 设计模式.装饰者模式;
public class Pearl extends Condiment {
/*在这里默认继承了Beverage 属性*/
private String name;
private double Price;
private int number;
//你也可以为装饰者实现一个无参构造使装饰者可以单独使用
public Pearl(Beverage beverage) {
setName("珍珠");
setNumber(1);
setPrice(0.4);
this.beverage = beverage;
}
}
五、装饰者模式的设计原则
类应该对扩展开放,对修改关闭
六、关键词
组合 嵌套