Java设计模式之装饰器模式----避免继承带来的类冗余问题

一.装饰器模式介绍


装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其结构。这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装。

这种模式创建了一个装饰类,用来包装原有的类,并在保持类方法签名完整性的前提下,提供了额外的功能。


  • 解决什么问题:为了扩展一个类的功能,经常会使用继承的方式实现,由于继承为类引入静态特征,并且随着扩展功能的增多,子类会很膨胀
  • 什么情况下使用:在不想增加很多子类,把子类变得膨胀的前提下扩展类
  • 如何解决:“组合”的思想

二.装饰者模式结构和实现


1.类图:

在这里插入图片描述

2.代码和解释:

Component是上层的一个抽象的接口,他提供一种公共的方法sampleOperation()

//.Component : 定义一个对象接口,可以给这些对象动态地添加职责。
interface Component {
     public void operation();
}

// ConcreteComponent : 实现 Component 定义的接口。
class ConcreteComponent implements Component {
    @Override
    public void operation() {
        System.out.println("初始行为");
    }
}

Decorator : 装饰抽象类,继承了 Component, 从外类来扩展 Component 类的功能

class Decorator implements Component {
    // 维护一个 Component 对象,和 Component 形成聚合关系
    protected Component component;
    
    // 传入要进一步修饰的对象
    public Decorator(Component component) {
        this.component = component;
    }
    @Override
    // 调用要修饰对象的原方法
    public void operation() {
        component.operation();
    }
}

ConcreteDecorator : 具体的装饰对象,起到给 Component对象 添加职责的功能。

class ConcreteDecoratorA extends Decorator {
    private String addedState = "newState";

    public ConcreteDecoratorA(Component component) {
        super(component);
    }
//对原方法进行了增强
    public void operation() {
       super.operation();
       System.out.println("add state: " + addedState);

    }
}

三.装饰者模式的应用 ----Java IO技术

1.IO体系

IO流用来处理设备之间的数据传输,Java程序中,对于数据的输入/输出操作 都是以“流”的方式进行的。java.io包下提供了各种“流”类的接口,用以获取不同种类的数据,并通过标准的方法输入或输出数据。
在这里插入图片描述

2.装饰器模式是如何应用的?

InputStream就是装饰者模式中的超类(Component)

注意,装饰者模式的超类并不一定是一个接口,因为接口和抽象类都有抽象的含义,个人认为要根据具体情况判断,代表“某种基础功能”的那个类或者接口就是Component.

package java.io;

//这里的InputStream就不是接口而是抽象类 它代表了输出流这种基本功能的组件
public abstract class InputStream implements Closeable {}

ByteArrayInputStream,FileInputStream相当于被装饰者(ConcreteComponent),他们都是对超类的直接继承,这些类都提供了最基本的字节读取功能。

FilterInputStream即是装饰者(Decorator),也是装饰类的基类,BufferedInputStream,DataInputStream,PushbackInputStream(都继承了FilterInputStream类)…这些都是被装饰者装饰后形成的成品,他们的目的是为了扩展FilterInputStream的功能。


public
class FilterInputStream extends InputStream {
    /**
     * The input stream to be filtered.
     */
    protected volatile InputStream in;

可以看到 FilterInputStream作为装饰者,继承了超类InputStream的同时,其内部维护了一个InputStream,这样就可以通过构造器方法传入InputStream对象然后对其进行功能扩展了。


public BufferedInputStream(InputStream in, int size) {
        super(in);
        if (size <= 0) {
            throw new IllegalArgumentException("Buffer size <= 0");
        }
        buf = new byte[size];
    }

这是BufferedInputStream,这个类就继承了FilterInputStream,调用其父类构造器同时,添加了缓冲区的新功能。

四.优缺点

优点:装饰类和被装饰类可以独立发展,不会相互耦合,装饰模式是继承的一个替代模式,装饰模式可以动态扩展一个实现类的功能。

缺点:多层装饰比较复杂

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值