Java设计模式(一)装饰者模式

154 篇文章 5 订阅
150 篇文章 6 订阅

一、基本概念

1.定义

装饰(Decorator)模式又叫做包装模式,其功能是动态地给一个对象添加一些额外的职责。就增加功能来说,装饰模式相比生成子类更为灵活,是继承关系的一个替换方案。

装饰模式可以在不创造更多子类的情况下,将对象的功能加以扩展。装饰模式把客户端的调用委派到被装饰类。装饰模式的关键在于这种扩展完全是透明的

装饰模式的应用在 java 的 I/O 流中最为显著。

2.适用环境

该模式的适用环境为:

(1)在不影响其他对象的情况下,以动态、透明的方式给单个对象添加职责。

(2)处理那些可以撤消的职责。

(3)当不能采用生成子类的方法进行扩充时。一种情况是,可能有大量独立的扩展,为支持每一种组合将产生大量的子类,使得子类数目呈爆炸性增长。另一种情况可能是因为类定义被隐藏,或类定义不能用于生成子类。

3.角色

  • 抽象构件角色(Component):通常是一个抽象类或者一个接口,定义了一系列方法,方法的实现可以由子类实现或者自己实现。通常不会直接使用该类,而是通过继承该类或者实现该接口来实现特定的功能。

  • 具体构件角色(Concrete Component):是 Component 的子类,实现了对应的方法,它就是那个被装饰的类。

  • 装饰角色(Decorator):是 Component 的子类,它是具体装饰角色共同实现的抽象类(也可以是接口),并且持有一个 Component 型的对象引用,它的主要作用就是把客户端的调用委派到被装饰类。

  • 具体装饰角色(Concrete Decorator):它是具体的装饰类,是 Decorator 的子类,当然也是 Component 的子类。它主要就是定义具体的装饰功能

4.uml图解

在这里插入图片描述


二、代码实现

被修饰基类——IComponentOutput接口

public interface IComponentOutput {
    void operator();
}

被修饰子类——Output类

public class Output implements IComponentOutput {
    @Override
    public void operator() {
        System.out.println("输出字节流");
    }
}

修饰基类——AbstractBuffer抽象类

public abstract class AbstractBuffer implements IComponentOutput {
	//修饰类需要引入被修饰类的基类对象,非常重要!!!
    private IComponentOutput output;

    public AbstractBuffer(IComponentOutput output) {
        this.output = output;
    }

    @Override
    public void operator() {
        output.operator();
    }
}

修饰实现类——Buffer1类

public class Buffer1 extends AbstractBuffer {
    public Buffer1(IComponentOutput output) {
        super(output);
    }

    @Override
    public void operator() {
        super.operator();
        this.b1();
    }

    void b1() {
        System.out.println("附加1");
    }
    
}

修饰实现类——Buffer2类

public class Buffer2 extends AbstractBuffer {

    public Buffer2(IComponentOutput output) {
        super(output);
    }

    @Override
    public void operator() {
        super.operator();
        this.b2();
    }

    void b2() {
        System.out.println("附加2");
    }
}

修饰实现类——Buffer3类

public class Buffer3 extends AbstractBuffer {

    public Buffer3(IComponentOutput output) {
        super(output);
    }

    @Override
    public void operator() {
        super.operator();
        this.b3();
    }

    void b3() {
        System.out.println("附加3");
    }
}

有三个修饰子类,用于额外添加不同的附加功能


测试类——Client类

public class Client {
    public static void main(String[] args) {

        IComponentOutput output = new Output();
        output.operator();

        System.out.println("===定制1===");
        AbstractBuffer b1 = new Buffer1(output);
        AbstractBuffer b2 = new Buffer2(b1);
        b2.operator();

        System.out.println("===定制2===");
        AbstractBuffer b3 = new Buffer3(output);
        b3.operator();
    }
}

执行结果为:
输出字节流
===定制1===
输出字节流
附加1
附加2
===定制2===
输出字节流
附加3

补充说明:
注意定制1这种方式:

AbstractBuffer b1 = new Buffer1(output);
AbstractBuffer b2 = new Buffer2(b1);

第二次的子类的参数是上一个已经修饰过的对象
这里的方法调用是:

Buffer2.operator()->AbstractBuffer.operator()+b()2
->output对象.operator()+b2()->b1.operator()+b2

这里的output对象就起了传递的作用
  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值