Java23种设计模式之装饰者模式的学习

源码链接(Gitee码云):https://gitee.com/oldou/javadesignpatterns
这里有我整理好的Java23种设计模式的源码以及博客教程,博客教程中介绍了Java23种设计的模式的各种实现方式以及应用场景,非常适用于学习以及提高我们的设计思维,如果对大家有所帮助,请记得star一下给予作者一定的精神支持,你的star是我写出更好的博客的动力,谢谢大家。

装饰模式(decorator)

职责(作用)

  • 动态的为一个对象增加新的功能;
  • 装饰模式是一种用于替代继承的技术, 无需通过继承增加子类就能扩展对象的新功能。使用对象的关联关系代替继承关系,这样更加灵活, 同时也能避免类型体系的快速膨胀。

实现细节

在这里插入图片描述

  • Component抽象构件角色
    真实对象和装饰对象有相同的接口。这样,客户端对象就能够与真实对象以相同的方式进行装饰对象交互。

  • ConcreteComponent 具体构件角色(真实对象)
    io流中的FileInputStream、FileOutputStream

  • Decorator装饰角色
    持有一个抽象构件的引用,装饰对象接受所有客户端的请求,并把这些请求转发给真实的对象,这样,就能在真实对象调用前后增加新的功能。

  • ConcreteDecorator具体装饰角色
    负责给构件对象增加新的责任。

简单案例说明

下面我们通过这么一个小案例来说明一下装饰模式,类图如下所示:
在这里插入图片描述
我们平时生活中的车只能再陆地上跑,而不能在水里游,天上飞等等,我们通过给车插上翅膀,那么它就能在天上飞了,通过给车加上浮沉箱,那么它就能在水上漂了,通过给车加上人工智能,那么它就能实现自动驾驶了…等等之类的,上面说白了就是在原有功能的基础上动态的增加新的功能,下面我们用代码来实现一下。我在源码中用注解详细的标注了。
代码测试

package com.oldou.decorator;

/**
 * 抽象构建
 */
public interface ICar {
    
    
    void move();//跑
}

/** ConcreteComponent
 * 具体构建角色(真实对象)
 */
class Car implements ICar{
    
    
    @Override
    public void move() {
    
    
        System.out.println("陆地上跑.....");
    }
}

/**
 * 装饰器角色
 */
class SuperCar implements ICar{
    
    
    protected ICar car; //需要持有真实对象的引用
    public SuperCar(ICar car) {
    
    
        super();
        this.car = car;
    }
    @Override
    public void move() {
    
    
        car.move();
    }
}
/** ConcreteDecorator具体装饰角色
 * 具体的装饰器1
 */
class FlyCar extends SuperCar{
    
    

    public FlyCar(ICar car) {
    
    
        super(car);
    }
    //增加新的功能
    public void fly(){
    
    
        System.out.println("可以天上飞了");
    }

    @Override
    public void move() {
    
    
        super.move();//调用原有的
        fly();//增加新的功能
    }
}

/** ConcreteDecorator具体装饰角色
 * 具体的装饰器 2
 */
class WaterCar extends SuperCar{
    
    
    public WaterCar(ICar car) {
    
    
        super(car);
    }
    //新的功能
    public void swim(){
    
    
        System.out.println("可以水里游了。。。");
    }

    @Override
    public void move() {
    
    
        super.move();
        swim();//增加上水里游的功能
    }
}

/** ConcreteDecorator具体装饰角色
 * 具体的装饰器 3
 */
class AICar extends SuperCar{
    
    
	//可以自己实现一下
}

客户端

package com.oldou.decorator;

import java.io.*;

/**
 * 设计模式之装饰者模式的测试
 */
public class Client {
    
    

    public static void main(String[] args) {
    
    

        Car car = new Car();
        car.move(); //真实角色只有在陆地上跑的功能

        System.out.println("增加新功能--");
        FlyCar flyCar = new FlyCar(car);//需要加入真实对象对其增加新的功能
        flyCar.move();
        System.out.println("**********************************");
        System.out.println("增加新的功能--");
        WaterCar waterCar = new WaterCar(car);
        waterCar.move();

        System.out.println("*******************两种功能都给安排上****************");
        WaterCar waterCar1 = new WaterCar(new FlyCar(new Car()));
        waterCar1.move();

       //Reader reader = new BufferedReader(new InputStreamReader(new FileInputStream(new File(""))));
    }
    /**
     * 以上的测试代码和我们之前所学习的I/O留非常相似
     * 例如:Reader reader = new BufferedReader(new InputStreamReader(new FileInputStream(new File(""))));
     * 这里的FileInputStream就相当于真实的对象,相当于我们这里的Car
     * InputStreamReader和 BufferedReader就相当于装饰器,我们这里的WaterCar和FlyCar
     */

}

测试结果:
在这里插入图片描述

开发中使用的场景

  • IO中输入流和输出流的设计;
  • Swing包中图形界面构件功能;
  • Servlet API 中提供了一个request对象的Decorator设计模式的默认实现类HttpServletRequestWrapper,HttpServletRequestWrapper类,增强了request对象的功能。
  • Struts2中,request,response,session对象的处理。

IO流实现细节

  • Component抽象构件角色:
    io流中的InputStream、OutputStream、Reader、Writer

  • ConcreteComponent 具体构件角色:
    io流中的FileInputStream、FileOutputStream

  • Decorator装饰角色:
    持有一个抽象构件的引用:io流中的FilterInputStream、FilterOutputStream

  • ConcreteDecorator具体装饰角色:
    负责给构件对象增加新的责任。Io流中的BufferedOutputStream、BufferedInputStream等。

在这里插入图片描述
在这里插入图片描述

装饰模式总结

总结

  • 装饰模式(Decorator)也叫包装器模式(Wrapper);
  • 装饰模式降低系统的耦合度,可以动态的增加或删除对象的职责,并使得需要装饰的具体构建类和具体装饰类可以独立变化,以便增加新的具体构建类和具体装饰类。

优点

  • 扩展对象功能,比继承灵活,不会导致类个数急剧增加;
  • 可以对一个对象进行多次装饰,创造出不同行为的组合,得到功能更加强大的对象;
  • 具体构建类和具体装饰类可以独立变化,用户可以根据需要自己增加新的具体构件子类和具体装饰子类。

缺点

  • 产生很多小对象。大量小对象占据内存,一定程度上影响性能。
  • 装饰模式易于出错,调试排查比较麻烦。

寄言

学习设计模式时一定要动手去敲代码,再加以理解,一定要熟悉到自己能够手写出来,因为面试的时候经常会让你手写出来(亲测)。如果本文对你有所帮助,记得点赞支持一下哈,谢谢。

源码链接(Gitee码云):https://gitee.com/oldou/javadesignpatterns
这里有我整理好的Java23种设计模式的源码以及博客教程,博客教程中介绍了Java23种设计的模式的各种实现方式以及应用场景,非常适用于学习以及提高我们的设计思维,如果对大家有所帮助,请记得star一下给予作者一定的精神支持,你的star是我写出更好的博客的动力,谢谢大家。

猜你喜欢

转载自blog.csdn.net/weixin_43246215/article/details/108577241