IO流中的设计模式


一、装饰器模式

Decorator装饰器:

装饰模式是在不必改变原类文件和不使用继承的情况下,动态的扩展一个对象的功能。它是通过创建一个包装对象,也就是装饰来包裹真实的对象。
注意其中的几点:
• 不改变原类文件
• 不使用继承
• 动态扩展
在这里插入图片描述
Component:
为统一接口,也是装饰类和被装饰类的基本类型。
ConcreteComponent:
为具体实现类,也是被装饰类,他本身是个具有一些功能的完整的类。
Decorator:
是装饰类,实现了Component接口的同时还在内部维护了一个ConcreteComponent的实例,并可以通过构造函数初始化。而Decorator本身,通常采用默认实现,他的存在仅仅是一个声明:我要生产出一些用于装饰的子类了。而其子类才是赋有具体装饰效果的装饰产品类。
ConcreteDecorator:
是具体的装饰产品类,每一种装饰产品都具有特定的装饰效果。可以通过构造器声明装饰哪种类型的ConcreteComponent,从而对其进行装饰。

代码实现

/**
 * 是装饰类和被装饰类的基础,统一的接口
 */
public interface Component {
    public void method();
}
/**
 * 被装饰类 是Component接口的具体实现
 */
public class ConctreteComponent implements Component {
    @Override
    public void method() {
        System.out.println("ConctreteComponent ...");
    }
}
/**
 * 装饰类
 * 实现了Component接口
 */
public abstract class Decorator implements Component {

    //内存维护了一个Component实例
    private Component component;

    //通过构造函数来实例化内存的component属性
    public Decorator(Component component) {
       this.component = component;
    }

    @Override
    public void method() {
        component.method();
    }
}
/**
 * 具体的装饰类A
 */
public class ConcreteDecoratorA extends Decorator {
    public ConcreteDecoratorA(Component component) {
        super(component);
    }

    public void methodA() {
        System.out.println("装饰器A提供的新的功能");
    }

    @Override
    public void method() {
        System.out.println("针对该方法添加一层包装");
        super.method();
        System.out.println("A包装结束");
    }
}

装饰器特点

它必须持有一个被装饰的对象(作为成员变量)。
它必须拥有与被装饰对象相同的接口(多态调用、扩展需要)
它可以给被装饰对象添加额外的功能。
总结:保持接口,动态增强性能。

装饰器在IO流中的使用

		/**
         * Inputstream相当于统一的接口,给被装饰类和装饰类的基本的类型
         * FileInputStream相当于原始的被封装的对象,为具体的实现类,他对inputstream方法有完整的实现
         */
        FileInputStream inputStream = new FileInputStream(path);


        /**
         * FilterInputStream是装饰类,其继承自InputStream基类
         * 内部存在一个InputStream实例,需要通过构造函数来实例化内部属性
         * /
         FilterInputStream extends InputStream {
    	protected volatile InputStream in;
         /**
         * BufferInputStream就是具体的装饰类 
         */
       BufferedInputStream bufferedInputStream = new BufferedInputStream(inputStream);
InputStream是被装饰类和装饰类的基本类型,这里是通过抽象类的形式提供的,相当于Component接口
FileInputStream是具体的被装饰类,是继承自InputStream,提供了完备的InputStream	方法的实现。相当于是concreateComponent类
FilterInputStream是装饰器类,其继承InpuStream,内部维护了一个Inpustream实现类,相当于Decorator类
BufferInputstream是具体的装饰器类,继承自FilterInputStream装饰器类,提供了具有特有的缓冲功能的特点

总结:

装饰器模式就是一个可以非常灵活的动态扩展类功能的设计模式,它采用组合的方式取代继承,使得各个功能的扩展更加独立和灵活。

适配器模式

Adapter适配器

适配器定义:将一个类的接口转换成客户希望的另外一个接口,Adapter模式使原本由于接口不兼容而不能一起工作的哪些类可以一起工作
适配器模式分两种:类适配器和对象适配器
• 使用继承(就是所谓的类适配器模式)
• 使用组合(所谓的对象适配器模式)

在这里插入图片描述
适配器所涉及的角色有:
Target(目标接口):所要转换的所期待的接口
Adaptee(源角色):需要适配的类
Adapter(适配器):将源角色适配成目标接口,一般持有源接口的引用(或者继承源接口),且实现目标接口。
Client(客户类):通过目标角色获取服务

代码实例

手机充电器适配:
存在一个Typec接口的充电器,期望提供一个USB接口的充电器

/**
 * 源角色,需要适配的类
 */
public class TypeC {
    public void typec(){
        System.out.println("TypeC 充电器实现");
    }
}
/**
 * 目标角色
 * 用户期望使用use充电器
 */
public interface USB {
    public void use();
}
/**
 * 适配器类
 * 将源角色适配成目标角色
 */
public class Adapter extends TypeC implements USB {

    @Override
    public void use() {
        super.typec();
    }
}

适配器特点

•优点
1、适配器对象实现原有接口
2、适配器对象组合一个实现新接口的对象(这个对象也可以不实现一个接口,只是一个单纯的对象)
3、对适配器原有接口方法的调用被委托给新接口的实例的特定方法(重写旧接口方法来调用新接口功能。)
• 缺点
过多使用适配器会使得系统非常凌乱,明明调用的是A接口,内部却被适配成了B接口。因此除非必要,不推荐使用适配器,而是直接对系统重构

适配器优缺点

• 优点
有更好的复用性。系统需要使用现有的类,但此类接口不符合系统需要,通过适配器模式让这些功能得到很好的复用
有更好的扩展性。实现适配器,可以调用自己开发的功能
适用场景
软件系统结构需要升级或扩展,又不想影响原有系统稳定运行的时候
转换类之间的差別不是很大的时候
想创建一个可以复用的类,该类可以与其他不相关类或不可预见类协同工作的时候

适配器在IO中的使用

在IO中适配器的使用也比较广泛
适配器角色就是InputStreamReader,
被适配的角色是InputStream类的实例对象,
目标接口是Reader类。
可以看到,InputStreamReader实现了Reader接口,并且持有了InputStream的引用,这里是通过StreamDecoder类间接持有的,因为从byte到char 要经过编码。

/******************Reader类(目标类)******************/
public abstract class Reader implements Readable, Closeable {
abstract public int read(char cbuf[], int off, int len) throws IOException;
abstract public void close() throws IOException;
}
/******************InputStreamReader类(适配器类)******************/
public class InputStreamReader extends Reader {
    private final StreamDecoder sd;
    //持有对被适配对象的引用
    public InputStreamReader(InputStream in) {
        super(in);
        try {
            //通过StreamDecoder类间接引用被适配的对象
            sd = StreamDecoder.forInputStreamReader(in, this, (String)null);
        } catch (UnsupportedEncodingException e) {
            // The default encoding should always be available
            throw new Error(e);
        }
    }
    //…(省略的代码)
 }
 /******************InputStream类(被适配类)******************/
 public abstract class InputStream implements Closeable {
 //代码省略
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值