什么时候使用装饰者模式?[英] When to Use the Decorator Pattern?

本文是小编为大家收集整理的关于什么时候使用装饰者模式?的处理/解决方法,可以参考本文帮助大家快速定位并解决问题,中文翻译不准确的可切换到English标签页查看源文。

问题描述

我正在浏览我的设计模式,而我尚未在编码中认真使用的一种模式是装饰器图案.

我理解了该模式,但是我想知道的是现实世界中一些良好的具体示例,即装饰物图案是最好/最佳/优雅的解决方案.对装饰图案的需求确实很方便的具体情况.

谢谢.

推荐答案

Decorator图案与流有关:您可以用流来包装流以添加功能.我已经看到了.NET框架 - 据我所知,这发生在其他地方.我最喜欢的是在文件流周围使用gzipstream,以增加压缩.

其他推荐答案

Decorator模式用于将其他功能添加到现有object(即在运行时已经实例化的类),而不是对象class和/或子类.通过将对象类的子类划分为整个对象,很容易在整个对象中添加功能,但是不可能通过这种方式扩展单个对象.使用Decorator图案,您可以将功能添加到一个对象中,并使其他物体未修改.

在Java中,装饰器模式的经典示例是Java I/O流实现.

FileReader       frdr = new FileReader(filename);
LineNumberReader lrdr = new LineNumberReader(frdr);

前面的代码创建了从文件读取并跟踪行号的读取器 - lrdr.第1行创建文件读取器(frdr),然后第2行添加行数跟踪.

实际上,我强烈建议您查看Java I/O类的Java源代码.

其他推荐答案

我最近在Web服务中使用了Decorator模式,该Web服务使用以下命令程序接口:

public Command receive(Request request);
public Response execute(Command command);
public void respond(Response response);

基本上,CommandProcessor接收请求并创建适当的命令,执行命令并创建适当的响应并发送响应.当我想添加计时并记录它时,我创建了一个使用现有命令处理器作为其组件的计时仪. TimerDecorator实现了CommandProcessor接口,但只会添加时间安排,然后调用其目标,这是真正的CommandProcessor.这样的东西:

public class TimerDecorator implements CommandProcessor {
   private CommandProcessor target;
   private Timer timer;

   public TimerDecorator(CommandProcessor processor) {
      this.target = processor;
      this.timer = new Timer();
   }

   public Command receive(Request request) {
      this.timer.start();
      return this.target.receive(request);
   }

   public Response execute(Command command) {
      return this.target.execute(command);
   }

   public void respond(Response response) {
      this.target.response(response);
      this.timer.stop();
      // log timer
   }

}

因此,真正的命令处理器被包装在timerDecorator中,我可以像目标命令程序一样对待计时器,但是现在添加了计时逻辑.

本文地址:https://www.itbaoku.cn/post/627736.html

问题描述

I am going over my design patterns, and one pattern I have yet to seriously use in my coding is the Decorator Pattern.

I understand the pattern, but what I would love to know are some good concrete examples of times in the real world that the decorator pattern is the best/optimal/elegant solution. Specific situations where the need for the decorator pattern is really handy.

Thanks.

推荐答案

The decorator pattern is used a lot with streams: you can wrap a stream with a stream to get added functionality. I've seen this with the .Net framework - as far as I know this occurs elsewhere. My favourite is using GZipStream around a FileStream, for added compression.

其他推荐答案

The Decorator Pattern is used for adding additional functionality to an existing object (i.e. already instantiated class at runtime), as opposed to object's class and/or subclass. It is easy to add functionality to an entire class of objects by subclassing an object's class, but it is impossible to extend a single object this way. With the Decorator Pattern, you can add functionality to a single object and leave others like it unmodified.

In Java, a classical example of the decorator pattern is the Java I/O Streams implementation.

FileReader       frdr = new FileReader(filename);
LineNumberReader lrdr = new LineNumberReader(frdr);

The preceding code creates a reader -- lrdr -- that reads from a file and tracks line numbers. Line 1 creates a file reader (frdr), and line 2 adds line-number tracking.

Actually, I'd highly encourage you to look at the Java source code for the Java I/O classes.

其他推荐答案

I've recently used the decorator pattern in a web service which uses the following CommandProcessor interface:

public Command receive(Request request);
public Response execute(Command command);
public void respond(Response response);

Basically, the CommandProcessor receives a Request and creates the proper Command, executes the Command and creates the appropriate Response, and sends the Response. When I wanted to add timing and log it, I created a TimerDecorator that used an existing CommandProcessor as its component. The TimerDecorator implements CommandProcessor interface, but just adds timing and then calls its target, which is the real CommandProcessor. Something like this:

public class TimerDecorator implements CommandProcessor {
   private CommandProcessor target;
   private Timer timer;

   public TimerDecorator(CommandProcessor processor) {
      this.target = processor;
      this.timer = new Timer();
   }

   public Command receive(Request request) {
      this.timer.start();
      return this.target.receive(request);
   }

   public Response execute(Command command) {
      return this.target.execute(command);
   }

   public void respond(Response response) {
      this.target.response(response);
      this.timer.stop();
      // log timer
   }

}

So the real CommandProcessor is wrapped inside TimerDecorator, and I can treat TimerDecorator just like the target CommandProcessor, but now timing logic has been added.