前言 :
装饰者模式可以看做是制作汉堡的过程,起初,他们都有一个共同的属性--都能吃,所以定义一个接口(Material),然后是面粉(flour),将面粉制作成面包(bread),上面加上肉(相当于继承Bread,形成了肉面包),当然上面也可以加上菜(相当于继承了Bread,形成了菜面包),抹上酱就形成了酱面包。你也可以在肉面包上加上菜,这样就形成了菜肉面包,然后在加上酱,就形成了酱菜肉面包
我cao,我又饿了
目录
一、理论
职责:
动态的为一个对象增加新的功能
装饰模式是一种用于替代继承的技术,无须通过继承来增加子类就能扩展对象的新的功能。使用对象的关联关系
代替继承关系,更加灵活,同时避免类型体系的快速膨胀。
实现细节:
Component 抽象构件角色
- 真实对象和装饰对象有着相同的接口,这样,客户端就能够以于真实对象相同的方式同装饰对象交互
ConcreteComponent具体构件角色(真实对象)
io流中的FileInputStream FileOutStream
Decorator装饰角色
持有一个抽象构件的引用,装饰对象接受所有客户端的请求,并把这些请求转发给真实的对象,这样,就在真实对象前后增减 新的功能
ConcreteDecorator具体装饰角色
二、实现代码
package Decorate2;
public interface Material {
void eat();
}
//底层面包
class Bread implements Material
{
@Override
public void eat() {
// TODO 自动生成的方法存根
System.out.println("我要吃面包");
}
}
//面包摊好,准备做汉堡
class SuperBread implements Material
{
private Material bread;//组合关系
public SuperBread(Material bread) {
super();
this.bread = bread;
}
@Override
//吃
public void eat() {
// TODO 自动生成的方法存根
bread.eat();
}
}
//加蔬菜
class VegetableBread extends SuperBread
{//继承就相当于往=往上加东西
public VegetableBread(Material bread) {
super(bread);
}
public void EatVegetable()
{
System.out.println("吃蔬菜");
}
@Override
public void eat() {
// TODO 自动生成的方法存根
super.eat();
EatVegetable();
}
}
class MeatBread extends SuperBread
{
@Override
public void eat() {
// TODO 自动生成的方法存根
super.eat();
EatMeat();
}
public MeatBread(Material bread) {
super(bread);
// TODO 自动生成的构造函数存根
}
public void EatMeat()
{
System.out.println("吃肉了啊啊啊");
}
}
调用:
package Decorate2;
public class Client {
public static void main(String[] args) {
Bread bread=new Bread();
VegetableBread vegetableBread2=new VegetableBread(new MeatBread(bread));
vegetableBread2.eat();
}
}
实现结果:
三、代码分析
VegetableBread vegetableBread2=new VegetableBread(new MeatBread(bread));
这句话首先将new好的bread给MeatBread
然后在将new 好的MeatBread赋值给VegetableBread对象
那么调用vegetable.eat()时先MeatBread的eat,而MeatBread的eat调用又会调用Bread.eat(),然后再调用eatMeat(),eatvegetable(),可以把调用看做是递归(栈)
四、应用场景
IO 中输入流和输出流的设计
Swing包中的图形界面构件功能
Servlet API中提供了一个request对象的Decorator设计模式的默认实现类HttpServletWrapper,HTTPServletRequestWrapper类,增强了request对象的功能
Struts2中,request,reponse,session对象的处理
五、总结
装饰模式也叫包装器模式
装饰模式降低系统的耦合度,可以动态的增加或者删除对象的职责,并使得需要装饰的具体装饰类可以独立的变化,以便增加新的具体构件类和具体装饰类。
优点:
扩展对象功能,比继承灵活,不会导致类的个数急剧增加
可以对一个对象进行多次装饰,创造出不同行为的组合,得到的功能更加强大的对象
具体构件类和具体装饰类可以独立的变化,用户可以根据需要自己增加新的具体构件子类和具体装饰子类
缺点:
产生很多小对象,大量的小对象占据内存,一定程度上影响性能
装饰模式易于出错,调试排查比较麻烦
装饰模式和桥接模式的区别
两个模式都是为了解决过多子类对象问题,但是他们的诱因不一样。桥接模式是对对象自身现有机制沿着多个维度变化,是既有部分不稳定。装饰模式是为了增加新的功能。