装饰设计模式基本理论
用途:在现实生活中,常常需要对现有产品增加新的功能或美化其外观,如房子装修、相片加相框等。在软件开发过程中,有时想用一些现存的组件。这些组件可能只是完成了一些核心功能。但在不改变其结构的情况下,可以动态地扩展其功能。所有这些都可以釆用装饰模式来实现。
实例解析:coffee是一种drink,能知道cost和info
1.了解coffee的cost和info
2.加入milk之后,coffee的cost和info
3.加入sugar之后,coffee的cost和info
4…加入milk和sugar之后,coffee的cost和info
- 定义抽象构件:定义一个抽象接口一规范准备接收附加责任的对象
public interface Drink {
double cost();//费用
String info();//说明
}
- 定义具体构件
//具体构件
public class Coffee implements Drink {
private String name = "原味咖啡";
@Override
public double cost() {
return 10;
}
@Override
public String info() {
return name;
}
}
- 定义抽象装饰:继承或实现抽象构件,并包含具体构件的实例,可以通过其子类扩展具体构件的功能。Drink milk = new Milk(new(Coffee)coffe,将coffe包装。
public abstract class Decorate implements Drink {
private Drink drink;
public Decorate(Drink drink){
this.drink = drink;
}
@Override
public double cost() {
return this.drink.cost();
}
@Override
public String info() {
return this.drink.info();
}
}
- 定义具体装饰:实现抽象装饰的相关方法,并给具体构件对象添加附加的责任。装饰类亦称作包装类
//具体装饰1
public class Milk extends Decorate {
public Milk(Drink drink) {
super(drink);
}
@Override
public double cost() {
return super.cost()*4;
}
@Override
public String info() {
return super.info()+"加入了牛奶";
}
}
// 具体装饰2
public class Sugar extends Decorate {
public Sugar(Drink drink) {
super(drink);
}
@Override
public double cost() {
return super.cost()*2;
}
@Override
public String info() {
return super.info()+"加入了蔗糖";
}
}
代码测试装饰类
public class DerocateTest {
public static void main(String[] args) {
//原味coffee
Drink coffe = new Coffee();
System.out.println(
coffe.info() + "======" + coffe.cost()
);
//添加牛奶
Drink milk = new Milk(coffe);
System.out.println(
milk.info() + "======" + milk.cost()
);
//添加糖
Drink suger = new Sugar(coffe);
System.out.println(
suger.info() + "======" + suger.cost()
);
//添加牛奶和糖
milk = new Milk(suger);
System.out.println(
milk.info() + "======" + milk.cost()
);
}
}
测试结果
原味咖啡======10.0
原味咖啡加入了牛奶======40.0
原味咖啡加入了蔗糖======20.0
原味咖啡加入了蔗糖加入了牛奶======80.0
InputStream就是我们所说的Component角色对象,FileInputStream就是对应的一个ConcreteComponent角色,FilterInputStream就是我们所说的Decorator角色,继承了Component角色,同时持有了一个Component对象,FilterInputStream也正如我们所介绍的,其方法当中的实现,基本上都是调用传入进来的Component接口的实现,它本身并不做装饰性操作,主要是让其子类去实现装饰性的工作。而BufferedInputStream就是ConcreteDecorator角色,其中也是持有了Component对象的。