概述
在不改变现有对象结构的情况下,动态地给对象增加一些职责.
通常情况下,扩展一个类的功能会使用继承方式来实现。但继承具有静态特征,耦合度高,并且随着扩展功能的增多,子类会很膨胀。
用组合关系来创建一个包装对象(即装饰对象)来包裹真实对象,并在保持真实对象的类结构不变的前提下,为其提供额外的功能,这就是装饰器模式的目标。下面来分析其基本结构和实现方法。
结构
装饰器模式主要包含以下角色:
1.抽象构件(Component)角色:定义一个抽象接口以规范准备接收附加责任的对象。
2.具体构件(ConcreteComponent)角色:实现抽象构件,通过装饰角色为其添加一些职责。
3.抽象装饰(Decorator)角色:继承抽象构件,并包含具体构件的实例,可以通过其子类扩展具体构件的功能。
4.具体装饰(ConcreteDecorator)角色:实现抽象装饰的相关方法,并给具体构件对象添加附加的责任。
案例
饭店有炒面,炒饭这些快餐,可以额外添加鸡蛋,火腿等配菜,加配菜需要额外加钱,那么计算总价就会显得麻烦.
//抽象构建角色
//快餐
interface FastFood{
float price();
String desc();
}
//具体构建角色
//炒饭
class FiredRice implements FastFood{
private static float ricePrice=9f;
private static String desc="炒饭";
public float price(){
return ricePrice;
}
public String desc(){
return desc;
}
}
//炒面
class FireNoodles implements FastFood{
private static float noodlesPrice=10f;
private static String desc="炒面";
@Override
public float price() {
return noodlesPrice;
}
@Override
public String desc() {
return desc;
}
}
//抽象装饰角色
abstract class Garnish implements FastFood{
private FastFood fastFood;
public Garnish(FastFood fastFood){
this.fastFood=fastFood;
}
public FastFood getFastFood() {
return fastFood;
}
public void setFastFood(FastFood fastFood) {
this.fastFood = fastFood;
}
public abstract float price();
public abstract String desc();
}
//具体装饰角色
//加蛋
class Egg extends Garnish{
private static float eggPrice=0.5f;
private static String eggDesc="加蛋";
public Egg(FastFood fastFood) {
super(fastFood);
}
@Override
public float price() {
return getFastFood().price()+eggPrice;
}
@Override
public String desc() {
return getFastFood().desc()+eggDesc;
}
}
//加火腿
class Ham extends Garnish{
private static float hamPrice=1f;
private static String hamDesc="加火腿";
public Ham(FastFood fastFood) {
super(fastFood);
}
@Override
public float price() {
return getFastFood().price()+hamPrice;
}
@Override
public String desc() {
return getFastFood().desc()+hamDesc;
}
}
测试
public class Test {
public static void main(String[] args) {
//炒饭加蛋加火腿
FastFood fastFood=new Ham(new Egg(new FiredRice()));
System.out.println(fastFood.desc()+"价格:"+fastFood.price());
}
}
炒饭加蛋加火腿价格:10.5
io中的装饰模式
BufferedWriter使用装饰者模式对writer子实现类实现了增强,增加了缓冲区.
抽象构建角色为writer,具体构建角色为InputStreamWriter,装饰角色为BufferedWriter
静态代理模式和装饰者模式的区别
相同点
- 都要实现和目标类相同的业务接口
- 在两个类中都要声明目标对象.
- 都可以在不修改目标类的前提下增强目标方法
不同点
- 目的不同
装饰者是为了增强对象
静态代理是为了保护和隐藏目标对象 - 目标对象的构建不同
装饰者模式是由外界传递进来,通过构造方法传递
代理模式是在对象内部创建,以此来隐藏目标对象.