Head First 设计模式之装饰者模式(Java例子)

前言:

来源于《head first 设计模式》。当作读书笔记了,这次看的是第三章装饰者模式。看得有点上瘾。。。抽出了点时间来总结一下。

装饰者模式的概念

动态地将责任附加到对象之上。想要扩展功能,装饰者提供有别于继承的另一种选择。

head fitst基本操作举个例子

head first里面举了两个例子,一个是星巴克一个我们熟悉的java i/o包。这里为了方便就用java i/o来展示我们的装饰者模式吧。

通用的观察者模式的uml图

惯例贴一下uml图,这是通用的观察者模式的uml图,我们看完它再来了解java i/o的会更好理解
在这里插入图片描述
Component:作用是规定了同一个父类,让每一个组件都可以单独使用或者被装饰者包含起来。
ConcreteComponent:这是我们要动态地加上新行为的对象,继承与Component.
Decorator:这是装饰者共同需要实现的接口或者继承的父类,它使每个装饰者都带有一个或者说是包含一个组件,即有一个实例变量来保存某一Component
ConcreteDecoraror:装饰者咯,可以拓展新的方法或者增加新的行为在旧的行为后面

Java i/o的uml:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1h1B6wlP-1586688264037)(https://imgblog.csdnimg.cn/20200412183344793.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2F3YWtlX2xxaA==,size_16,color_FFFFFF,t_70)]
并没有把所有的类都写出了,写了几个点名关系即可了。
InputStream:相当于上方的component
FileInputStream:相当于被修饰的对象
StringBufferInputStream:相当于被修饰的对象
FilterInputStream:修饰者共同的父类了,里面包含了一个inputstream实例。

LowerCaseInputStream代码:

public class LowerCaseInputStream extends FilterInputStream {
    protected LowerCaseInputStream(InputStream in) {
        super(in);
    }
    //针对字节流
    public  int read() throws IOException{
        int c=super.read();
        return (c==-1?c:Character.toLowerCase(((char)c)));
    }
    //针对字节数组
    public int read(byte[] b,int offset,int len) throws IOException {
        int result=super.read(b,offset,len);
        for (int i=offset;i<offset+result;i++){
            b[i]= (byte) Character.toLowerCase(((char)b[i]));
        }
        return  result;
    }
}

测试代码:

public class InputTest {
    public static void main(String[] args) {
        int c;
        try {
        InputStream in=new LowerCaseInputStream(
                new BufferedInputStream(
                new FileInputStream("./test.txt")));
        while ((c=in.read())>=0){
            System.out.print((char)c);
        }
            in.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

总结:

InputStream in=new LowerCaseInputStream(
                new BufferedInputStream(
                new FileInputStream("./test.txt")));

这是平常我们书写一个读取类基本的写法把,类似于套娃。我们可以理解为我们先用BufferedInputStream修饰了组件FileInputStream,再用我们自己的LowerCaseInputStream修饰了BufferedInputStream。read的方法的调用就先调用FileInputStream从文件中读取然后到BufferedInputStream用字符流再到LowerCaseInputStream转化为小写,这样统分体现了装饰者模式对方法的扩展,又不会影响上层代码,同时对于java i/o这种类别特别多已经功能又重复,或者再某个类基础上加强的,最为适用。
装饰者模式简单来讲其实就是:动态的给一个对象添加一些额外的功能,而无需修改上层代码。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章