JAVA装饰器模式

装饰器模式允许你向一个现有的对象添加新的功能,同时又不改变其结构,它是作为现有的类的一个包装。这种模式创建了一个装饰类,用来包装原有的类,并在保持类方法签名完整性的前提下,提供了额外的功能。他的目的主要是动态地给一个对象添加一些额外的职责。就增加功能来说,装饰器模式相比生成子类更为灵活。他主要解决的问题是我们为了扩展一个类经常使用继承方式实现,由于继承为类引入静态特征,并且随着扩展功能的增多,子类会很膨胀。那么我们何时使用呢?在不想增加很多子类的情况下扩展类。如何解决?将具体功能职责划分,同时继承装饰者模式。关键代码: 1、Component 类充当抽象角色,不应具体实现。 2、修饰类(Decorator)引用和继承 Component 类3、具体扩展类(ConcreteComponent)继承 Component 类,重写父类方法。示例代码我们去咖啡馆点咖啡的时候,通常会点具体的咖啡单品,然后再点一些咖啡调料。咖啡种类(具体类):Espresso、ShortBlack、LongBlack、Decaf调料(装饰类):Milk、Soy、Chocolate1、抽象接口// 饮料
public abstract class Drink {

// 描述
private String description = "";

// 价格
private float price = 0f;

public void setDescription(String description) {
    this.description = description;
}

public String getDescription() {
     return "{描述:"+description + "-" + this.getPrice()+"}";
}

public float getPrice() {
    return price;
}

public void setPrice(float price) {
    this.price = price;
}

// 花费
public abstract float cost();

}2、定义具体类咖啡父类// 咖啡
public class Coffee extends Drink {

@Override
public float cost() {
    return super.getPrice();
}

}低咖// 低咖
public class Decaf extends Coffee {

public Decaf() {
    super.setDescription("Decaf");
    super.setPrice(3.0f);
}

}意大利浓咖啡// 意大利浓咖啡
public class Espresso extends Coffee {

public Espresso() {
    super.setDescription("Espresso");
    super.setPrice(4.0f);
}

}
美式咖啡// 美式咖啡
public class LongBlack extends Coffee {

public LongBlack() {
    super.setDescription("LongBlack");
    super.setPrice(6.0f);
}

}黑咖啡// 黑咖啡
public class ShortBlack extends Coffee {

public ShortBlack() {
    super.setDescription("ShortBlack");
    super.setPrice(5.0f);
}

}
3、定义装饰类调料父类public class Decorator extends Drink {

private Drink drink;

public Decorator(Drink drink) {
    this.drink = drink;
}

@Override
public float cost() {
    return super.getPrice() + drink.cost();
}

@Override
public String getDescription() {
     return "[===="+super.getDescription()  + "&&" + drink.getDescription()+"====]";
}

}
巧克力public class Chocolate extends Decorator {

public Chocolate(Drink drink) {
	super(drink);
	super.setDescription("Chocolate");
	super.setPrice(3.0f);
}

}牛奶public class Milk extends Decorator {

public Milk(Drink drink) {
    super(drink);
    super.setDescription("Milk");
    super.setPrice(2.0f);
}

}
咖啡豆public class Soy extends Decorator {

public Soy(Drink drink) {
    super(drink);
    super.setDescription("Soy");
    super.setPrice(1.5f);
}

}测试public class CoffeeBar {

public static void main(String[] args) {

    Drink order;
    order = new Decaf();
    System.out.println("order1 price:" + order.cost());
    System.out.println("order1 desc:" + order.getDescription());

    System.out.println("****************");
    order = new LongBlack();
    order = new Milk(order);
    order = new Chocolate(order);
    order = new Chocolate(order);
    System.out.println("order2 price:" + order.cost());
    System.out.println("order2 desc:" + order.getDescription());

}

}运行结果:order1 price:3.0
order1 desc:{描述:Decaf-3.0}


order2 price:14.0
order2 desc:[{描述:Chocolate-3.0}&&[{描述:Chocolate-3.0}&&[{描述:Milk-2.0}&&{描述:LongBlack-6.0}]]]总结优点:装饰类和被装饰类可以独立发展,不会相互耦合,装饰模式是继承的一个替代模式,装饰模式可以动态扩展一个实现类的功能。缺点:多层装饰比较复杂。使用场景: 1、扩展一个类的功能。 2、动态增加功能,动态撤销。注意事项:动态的将新功能附加到对象上。在对象功能扩展方面,它比继承更有弹性。可代替继承。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值