设计模式——装饰器模式(Decorator Pattern)+ Spring相关源码

这篇具有很好参考价值的文章主要介绍了设计模式——装饰器模式(Decorator Pattern)+ Spring相关源码。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、装饰器模式的定义

  • 别名:包装模式(Wrapper Pattern)
  • 类型:结构型模式。
  • 目的:指在不改变现有对象结构的情况下,动态地给该对象增加一些职责额外功能。

二、个人理解

给对象添加新功能时,并不是在对象类中直接添加,而是在装饰器类中添加。
在装饰类中添加新功能,你可以增强原先对象的方法,也可以给对象新增一个方法。

举个抽象的例(可能并不是很贴切)

假设要给人类添加开炮功能。
但由于这是人类,咱们不能通过继承直接给人类添加开炮功能
所以我们就得通过组合,将机器和人类组合起来、通过变相实现人类可以开炮。
这个机器就是装饰器。

  • 坦克 + 人类 ,实现开炮功能
  • 高达 + 人类 ,实现开炮功能

三、例子

1、菜鸟教程例子

菜鸟教程的例子都将对象和装饰器进行了抽象处理,实现了可替换对象和装饰器的实现类。
菜鸟教程原例子
个人觉得这样理解装饰器太绕了,下面的例子就只保留了对象和装饰器

1.1、定义对象

定义一个圆的对象

public class Circle{
   @Override
   public void draw() {
      System.out.println("Shape: Circle");
   }
}

1.2、定义装饰器

新增setRedBorder方法去设置红色边框。

public class RedCircleDecorator{
   private Circle c;
   public RedCircleDecorator(Circle c) {
      this.c = c;
   }
 
   @Override
   public void draw() {
      decoratedShape.draw();         
      setRedBorder(decoratedShape);
   }
 
   private void setRedBorder(Circle decoratedShape){
      System.out.println("Border Color: Red");
   }
}

但我觉这个菜鸟这个例子并不能把装饰器模式特点表现出来
因setRedBorder是私有,并且只是把原先draw方法进行了增强。
这样的话,代理模式也能实现,代理模式也能增强原有的方法,所以这里并不能把装饰器模式特点表现出来
所以我改了一下。

public class ColorCircleDecorator{
   private Circle c;
   public RedCircleDecorator(Circle c) {
      this.c = c;
   }
 
   @Override
   public void draw() {
      decoratedShape.draw();
      System.out.println("画了个普通的圆");         
   }
 
   public void drawRedCircle(Circle decoratedShape){
   	  decoratedShape.draw();
      System.out.println("画了个红色的圆");
   }
   public void drawBlueCircle(Circle decoratedShape){
      decoratedShape.draw();
      System.out.println("画了个蓝色的圆");
   }
}

这个例子保留了原先的draw功能,又新增了drawRedCircle和drawBlueCircle功能。

3、JDK源码 ——包装类

包装类也运用了装饰器模式。
将基本类型 转 包装类 的同时,还提供各种转换类型的功能。

4、JDK源码 —— IO、OutputStreamWriter

OutputStreamWriter同时运用了装饰器模式+适配器模式。
这里我们拿装饰器部分来讲。

FileOutputStream fos = new FileOutputStream(new File("Y:/学习资料.md"));
OutputStreamWriter osw = new OutputStreamWriter(fos);
osw.append("新资料xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");

原本FileOutputStream 是原本没有append功能的,
而在中OutputStreamWriter 添加append功能。
源码:

public class OutputStreamWriter extends Writer {
	private final StreamEncoder se;
	
	public OutputStreamWriter(OutputStream out) {
        super(out);
        se = StreamEncoder.forOutputStreamWriter(out, lockFor(this),
                out instanceof PrintStream ps ? ps.charset() : Charset.defaultCharset());
    }
    @Override
    public Writer append(CharSequence csq) throws IOException {
        if (csq instanceof CharBuffer) {
            se.write((CharBuffer) csq);
        } else {
            se.write(String.valueOf(csq));
        }
        return this;
    }
}
 

可以看到虽然OutputStreamWriter 重写了append方法。
但构造器里OutputStream又被新的装饰器StreamEncoder接收。
而StreamEncoder类就已经通过继承Writer 增加了append方法。

public final class StreamEncoder extends Writer {
	private final OutputStream out;
    private StreamEncoder(OutputStream out, Object lock, CharsetEncoder enc) {
        super(lock);
        this.out = out;
        this.ch = null;
        this.cs = enc.charset();
        this.encoder = enc;

        this.bb = ByteBuffer.allocate(INITIAL_BYTE_BUFFER_CAPACITY);
        this.maxBufferCapacity = MAX_BYTE_BUFFER_CAPACITY;
    }
	public static StreamEncoder forOutputStreamWriter(OutputStream out, Object lock, Charset cs) {
        return new StreamEncoder(out, lock, cs);
    }
}

5、Spring源码 —— BeanWrapperImpl

BeanWrapperImpl类是对BeanWrapper接口的默认实现,它包装了一个bean对象,缓存了bean的内省结果,并可以访问bean的属性、设置bean的属性值。

BeanWrapperImpl功能还挺复杂的,大家可以自行去看源码,我就不贴出来了。

5、SpringMVC源码 —— HttpHeadResponseDecorator

HttpHeadResponseDecorator 给ServerHttpResponse 添加了writeWith、writeAndFlushWith的功能。

public class HttpHeadResponseDecorator extends ServerHttpResponseDecorator {
    public HttpHeadResponseDecorator(ServerHttpResponse delegate) {
        super(delegate);
    }

    public final Mono<Void> writeWith(Publisher<? extends DataBuffer> body) {
        return this.shouldSetContentLength() && body instanceof Mono ? ((Mono)body).doOnSuccess((buffer) -> {
            if (buffer != null) {
                this.getHeaders().setContentLength((long)buffer.readableByteCount());
                DataBufferUtils.release(buffer);
            } else {
                this.getHeaders().setContentLength(0L);
            }

        }).then() : Flux.from(body).doOnNext(DataBufferUtils::release).then();
    }

    private boolean shouldSetContentLength() {
        return this.getHeaders().getFirst("Content-Length") == null && this.getHeaders().getFirst("Transfer-Encoding") == null;
    }

    public final Mono<Void> writeAndFlushWith(Publisher<? extends Publisher<? extends DataBuffer>> body) {
        return this.setComplete();
    }
}


四、其他设计模式

创建型模式
结构型模式

  • 1、设计模式——装饰器模式(Decorator Pattern)+ Spring相关源码

行为型模式文章来源地址https://www.toymoban.com/news/detail-737675.html

  • 1、设计模式——访问者模式(Visitor Pattern)+ Spring相关源码
  • 2、设计模式——中介者模式(Mediator Pattern)+ JDK相关源码
  • 3、设计模式——策略模式(Strategy Pattern)+ Spring相关源码
  • 4、设计模式——状态模式(State Pattern)
  • 5、设计模式——命令模式(Command Pattern)+ Spring相关源码
  • 6、设计模式——观察者模式(Observer Pattern)+ Spring相关源码
  • 7、设计模式——备忘录模式(Memento Pattern)
  • 8、设计模式——模板方法模式(Template Pattern)+ Spring相关源码
  • 9、设计模式——迭代器模式(Iterator Pattern)+ Spring相关源码
  • 10、设计模式——责任链模式(Chain of Responsibility Pattern)+ Spring相关源码
  • 11、设计模式——解释器模式(Interpreter Pattern)+ Spring相关源码

到了这里,关于设计模式——装饰器模式(Decorator Pattern)+ Spring相关源码的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包