美文网首页
装饰者模式

装饰者模式

作者: 山不转人自转 | 来源:发表于2020-12-01 18:07 被阅读0次

1.什么是装饰者模式

口诀:是你,还有你,一切拜托你

动态给对象增加功能,从一个对象的外部来给对象添加功能,相当于改变了对象的外观,比用继承的方式更加的灵活。
当使用装饰后,从外部系统的角度看,就不再是原来的那个对象了,而是使用一系列的装饰器装饰过后的对象。

结构

角色:

Component:组件对象的抽象接口,可以给这些对象动态的增加职责/功能。
ConcreteComponent:具体的组件的对象,实现组件对象的接口,是被装饰器装饰的原始对象,即可以给这个对象动态的添加职责。
Decorator:所有装饰器的抽象父类,实现了组件对象的接口,并且持有一个组件对象(被装饰的对象)。
ConcreteDecorator:具体的装饰器,具体实现向装饰对象添加功能。
3.示例

下面我们用装饰者模式实现如下的功能:更多:设计模式聚合

要求用户输入一段文字,比如 Hello Me,然后屏幕输出几个选项

加密
反转字符串
转成大写
转成小写
扩展或者剪裁到10个字符,不足部分用!补充
用户输入 任意组合,比如 1,3 表示先执行1的逻辑,再执行3的逻辑
根据用户输入的选择,进行处理后,输出结果

//组件对象的接口  
public interface ICompoment {  
     String display(String str);  
}  
//具体的组件对象  
public class DetailCompoment implements ICompoment {  
    @Override  
    public String display(String str) {  
        System.out.println("原来内容:"+str);  
        return str;  
    }  
}  
//所有装饰器的父类,实现了组件接口  
public abstract class Decorator implements ICompoment{  
      //持有了一个组件对象  
      protected ICompoment compoment;  
      public Decorator(ICompoment compoment) {  
            this.compoment = compoment;  
      }  
      @Override  
      public String display(String str) {  
            return compoment.display(str);  
      }  
      //对组件对象进行装饰的抽象方法  
      public abstract String transform(String str);  
}  
//加密、解密工具类  
public class EnDecodeUtil {  
    private static final char password='a';  
    public static String encodeDecode(String str){  
        char[] chars = str.toCharArray();  
        for (int i = 0; i < chars.length; i++) {  
            chars[i] = (char) (chars[i] ^ password);  
        }  
        return new String(chars);  
    }  
}  
//加密装饰器  
public class EncodeDecorator extends Decorator {  
    public EncodeDecorator(ICompoment compoment) {  
        super(compoment);  
    }  
    @Override  
    public String display(String str) {  
        String display = super.display(str);  
        return transform(display);  
    }  
    @Override  
    public String transform(String str) {  
        System.out.println("invoke EncodeDecorator....");  
       return EnDecodeUtil.encodeDecode(str);  
    }  
}  
//解密装饰器  
public class DecodeDecorator extends Decorator {  
    public DecodeDecorator(ICompoment compoment) {  
        super(compoment);  
    }  
    @Override  
    public String display(String str) {  
        String display = super.display(str);  
        return transform(display);  
    }  
    @Override  
    public String transform(String str) {  
        System.out.println("invoke DecodeDecorator...");  
        return EnDecodeUtil.encodeDecode(str);  
    }  
}  
//反转 装饰器  
public class ReverseDecorator extends Decorator {  
    public ReverseDecorator(ICompoment compoment) {  
        super(compoment);  
    }  
    @Override  
    public String display(String str) {  
        String display = super.display(str);  
        String transformtransform = transform(display);  
        return transform;  
    } 
    @Override  
    public String transform(String str) {  
        System.out.println("invoke ReverseDecorator....");  
        StringBuilder sb = new StringBuilder(str);  
        return sb.reverse().toString();  
    }  
}  
//转为大写的装饰器  
public class UpperDecorator extends Decorator {  
    public UpperDecorator(ICompoment compoment) {  
        super(compoment);  
    }  
    @Override  
    public String display(String str) {  
        String display = super.display(str);  
        String transformtransform = transform(display);  
        return transform;  
    }  
    @Override 
     public String transform(String str) {  
        System.out.println("invoke UpperDecorator....");  
        return str.toUpperCase();  
    }  
}  
//转为大写的装饰器  
public class UpperDecorator extends Decorator {  
    public UpperDecorator(ICompoment compoment) {  
        super(compoment);  
    }  
    @Override  
    public String display(String str) {  
        String display = super.display(str);  
        String transformtransform = transform(display);  
        return transform;  
    }  
    @Override  
    public String transform(String str) {  
        System.out.println("invoke UpperDecorator....");  
        return str.toUpperCase();  
    }  
}  
//转为小写的装饰器  
public class LowerDecorator extends Decorator{  
    public LowerDecorator(ICompoment compoment) {  
        super(compoment);  
    }  
    @Override  
    public String display(String str) {  
        String display = super.display(str);  
        String transformtransform = transform(display);  
        return transform;  
    }  
    @Override  
    public String transform(String str) {  
        System.out.println("invoke lowerDecorator....");  
        return str.toLowerCase();  
    }  
}  
//裁剪、扩充装饰器  
public class ExtendOrSplitDecorator extends Decorator {  
    public ExtendOrSplitDecorator(ICompoment compoment) {  
        super(compoment);  
    }  
    @Override  
    public String display(String str) {  
        String display = super.display(str);  
        String transformtransform = transform(display);  
        return transform;  
    }  
    @Override  
    public String transform(String str) {  
        System.out.println("invoke ExtendOrSplitDecorator....");  
        if (str != null) {  
            if (str.length() > 10) {  
                return str.substring(0,10);  
            }else{  
                int repeatCount = 10 -str.length();  
                StringBuilder sb = new StringBuilder(str);  
                for (int i = 0; i < repeatCount; i++) {  
                    sb.append("!");  
                }  
                return sb.toString();  
            }  
        }  
        return null;  
    }  
}  
//裁剪、扩充装饰器  
public class ExtendOrSplitDecorator extends Decorator {  
    public ExtendOrSplitDecorator(ICompoment compoment) {  
        super(compoment);  
    }  
    @Override  
    public String display(String str) {  
        String display = super.display(str);  
        String transformtransform = transform(display);  
        return transform;  
    }  
    @Override  
    public String transform(String str) {  
        System.out.println("invoke ExtendOrSplitDecorator....");  
        if (str != null) {  
            if (str.length() > 10) {  
                return str.substring(0,10);  
            }else{  
                int repeatCount = 10 -str.length();  
                StringBuilder sb = new StringBuilder(str);  
                for (int i = 0; i < repeatCount; i++) {  
                    sb.append("!");  
                }  
                return sb.toString();  
            }  
        }  
        return null;  
    }  
}  
//测试代码  
public static void main(String[] args) {  
        //将输入内容转为大写,再反转  
        ReverseDecorator reverseDecorator = new ReverseDecorator(new UpperDecorator(new DetailCompoment()));  
        String display = reverseDecorator.display("wo shi zhongguo ren.");  
        System.out.println(display);  
        //将输入内容转为小写,在裁剪或者扩展 
         ExtendOrSplitDecorator decorator = new ExtendOrSplitDecorator(new LowerDecorator(new DetailCompoment()));  
        String display1 = decorator.display("I Love");  
        System.out.println(display1);  
        //将输入内容转为小写,再反转,然后加密  
        EncodeDecorator decorator1 = new EncodeDecorator(new ReverseDecorator(new LowerDecorator(new DetailCompoment())));  
        String display2 = decorator1.display("顶级机密:1941年12月 日本偷袭珍珠港! 银行密码是:1234ADC");  
        System.out.println(display2);  
        System.out.println("++++++++++");  
        //将输入内容先反转、再转为小写,然后加密  
        EncodeDecorator decorator2 = new EncodeDecorator(new LowerDecorator(new ReverseDecorator(new DetailCompoment())));  
        String display3 = decorator2.display("顶级机密:1941年12月 日本偷袭珍珠港! 银行密码是:1234ADC");  
        System.out.println(display3);  
        System.out.println("============");  
        //对上面的加密内容,进行解密  
        DecodeDecorator decodeDecorator = new DecodeDecorator(decorator1);  
        String display4 = decodeDecorator.display("顶级机密:1941年12月 日本偷袭珍珠港! 银行密码是:1234ADC");  
        System.out.println(display4);  
    } 

控制台输出:

原来内容:wo shi zhongguo ren.  
invoke UpperDecorator....  
invoke ReverseDecorator....  
.NER OUGGNOHZ IHS OW  
原来内容:I Love  
invoke lowerDecorator....  
invoke ExtendOrSplitDecorator....  
i love!!!!  
原来内容:顶级机密:1941年12月 日本偷袭珍珠港! 银行密码是:1234ADC  
invoke lowerDecorator....  
invoke ReverseDecorator....  
invoke EncodeDecorator....  
 URSP[晎硠宧蠭钗A⦆湎玁玬裌倖杍斄A杩SP帕PUXPサ宧杛细頗  
++++++++++  
原来内容:顶级机密:1941年12月 日本偷袭珍珠港! 银行密码是:1234ADC  
invoke ReverseDecorator....  
invoke lowerDecorator....  
invoke EncodeDecorator....  
 URSP[晎硠宧蠭钗A⦆湎玁玬裌倖杍斄A杩SP帕PUXPサ宧杛细頗  
============  
原来内容:顶级机密:1941年12月 日本偷袭珍珠港! 银行密码是:1234ADC  
invoke lowerDecorator....  
invoke ReverseDecorator....  
invoke EncodeDecorator....  
invoke DecodeDecorator... 
 cda4321:是码密行银 !港珠珍袭偷本日 月21年1491:密机级顶

装饰者模式在jdk中的应用I/O

image.png
 //这里FileInputStream 相当于组件对象,BufferedInputStream这个装饰器装饰了FileInputStream对象  
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(new File("fileName")));  
byte[] buff = new byte[1024];  
bis.read(buff);  
System.out.println(new String(buff)); 

5.优点、缺点,使用场合

优点:

1.比继承更灵活

从为对象添加功能的角度来看,装饰者模式比继承更为灵活。继承是静态的,一旦继承,所有的子类都有一样的功能。装饰者模式采用把功能分离到每个装饰器当中,
通过对象组合的方式,在运行时动态的组合功能,被装饰对象最终由哪些功能,是由运行时动态组合的功能决定的。

2.复用功能更容易

装饰模式把一系列复杂的功能分散到每个装饰器中,一般情况下每个装饰器只实现一个功能,使得实现装饰器变得简单,有利于装饰器功能的复用,可以给一个对象添加
多个装饰器,也可以把一个装饰器装饰多个对象,从而实现复用装饰器的功能。

3.简化高层定义

装饰者模式可以通过组合装饰器的方式,为对象添加任意多的功能;因此在高层定义的时候,不必把所有的功能都定义处理,只需要定义最基本的就可以了,在需要的时候可以
通过组合装饰器的方式来完成所需的功能。

缺点:会产生较多的细粒度的对象

装饰模式把一系列复杂的功能分散到每个装饰器中,一般情况下每个装饰器只实现一个功能,这样会产生很多细粒度的对象,并且功能越复杂,细粒度对象越多。

本质:动态组合

注意:装饰者模式只是改变组件对象的外观Facde,并没有改变其内核

使用场合:

如果需要再不影响其他对象的情况下,以动态、透明的方式给对象增加职责,可以使用装饰者模式。
如果不适合使用子类进行扩展的时候,可以考虑使用装饰者模式。装饰者模式使用的是对象组合的方式。
不适合子类扩展:比如扩展功能需要的子类太多,造成子类数量呈爆炸性增长。

相关文章

  • 如何利用装饰者模式在不改变原有对象的基础上扩展功能

    目录 什么是装饰者模式 普通示例 装饰者模式示例 类图关系 装饰者模式使用场景 装饰者模式优点 装饰者模式缺点 什...

  • 装饰者模式

    装饰者模式 装饰者模式和适配器模式对比 装饰者模式 是一种特别的适配器模式 装饰者与被装饰者都要实现同一个接口,主...

  • java IO 的知识总结

    装饰者模式 因为java的IO是基于装饰者模式设计的,所以要了解掌握IO 必须要先清楚什么事装饰者模式(装饰者模式...

  • 设计模式-装饰者模式

    装饰者模式概念: 装饰者模式又名包装(Wrapper)模式。装饰者模式以对客户端透明的方式扩展对象的功能,是继承关...

  • java - 装饰者模式

    装饰者模式 装饰者模式:动态将责任添加到对象上。如果需要扩展功能,装饰者提供了比继承更有弹性的解决方案。装饰者模式...

  • 设计模式之装饰者模式(Decorator Pattern)

    What: 装饰者模式又名包装(Wrapper)模式。装饰者模式动态地将责任附加到对象身上。若要扩展功能,装饰者提...

  • 装饰者(Decorator)模式

    装饰者(Decorator)模式装饰模式又名包装(Wrapper)模式。装饰模式是继承关系的一个替代方案。装饰模式...

  • 2、装饰者模式

    装饰者模式 一、基本概念 二、结构 三、案例1、装饰者模式案例2、JavaIO中使用装饰者模式 四、总结 一、基本...

  • PHP的设计模式-装饰者模式

    装饰者模式 装饰者模式 装饰者模式类似蛋糕,有草莓味、奶酪等种类,但是它们的核心都是蛋糕。 不断地将对象添加装饰的...

  • 设计模式 | 装饰者模式及典型应用

    前言 本文的主要内容: 介绍装饰者模式 示例 源码分析装饰者模式的典型应用Java I/O 中的装饰者模式spri...

网友评论

      本文标题:装饰者模式

      本文链接:https://www.haomeiwen.com/subject/zjgbfctx.html