首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >设计师违反设计模式是一种关系

设计师违反设计模式是一种关系
EN

Stack Overflow用户
提问于 2014-04-27 05:25:45
回答 2查看 431关注 0票数 5

我最近开始研究装饰设计模式,但我有一个疑问。装饰人员实现与他们试图装饰的组件相同的接口。这不违反我们之间的关系吗。此外,既然装饰器具有组件(通过组合),为什么真正需要装饰器实现与具体组件实现的相同的组件接口?

首先回顾一下装饰师的设计模式,让我感觉到装饰师可以直接实现组件。没有必要为装饰器设置抽象类/接口。

我担心这可能是一个愚蠢的问题,但帮助我有一个坚实的基础。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-04-27 06:16:43

理解构图和装饰的区别是很重要的。装饰器是一种组合形式,但区别于它的主要原因是,它的实现方式允许通常使用修饰对象的代码使用包装器。

让我们使用一个常见的例子来帮助探讨这个问题。考虑一下接口InputStream。我可能有一个将字节从一个流复制到另一个流的方法:

代码语言:javascript
运行
复制
public static void copy(InputStream in, OutputStream out) { ... }

现在假设我们有一个想要复制的文件。我会创建一个FileInputStream并将其传递给copy()

但是假设我得到了一个要求,我需要计算复制的字节数。

我可以创建扩展CountingFileInputStreamFileInputStreamCountingFileInputStream是-一个FileInputStream。但是如果明天我需要为SocketInputStream做同样的事情呢?我必须创建一个扩展CountingSocketInputStreamSocketInputStream

我可以用作文代替!我可以创建一个类,它接受一个InputStream并计算读取到它的字节数:

代码语言:javascript
运行
复制
public class StreamCounter {

   private final InputStream in;
   private long bytesRead;

   public int read() {
     int nextByte = in.read();
     if (nextByte != -1) bytesRead++;
     return nextByte;
   }
}

这可以处理任何InputStream,这是很棒的。但是我们不能使用使用InputStream的现有代码,因为StreamCounter 不是 InputStream

所以这就是Decorator进来的地方。相反,我们可以创建一个CountingInputStream,它同时实现InputStream (因此是一个 InputStream),并将其委托给另一个InputStream。这样我们就可以在我们的copy()方法中使用它。

因此,简而言之,就is-a关系而言,CountingInputStream是--一种InputStream (通常是我们所关心的一切),但不是FileInputStream,它允许包装任何InputStream,就像LimitInputStream正在装饰DeflaterInputStream,而BufferedInputStream正在装饰FileInputStream。到头来,copy()不需要关心!

票数 1
EN

Stack Overflow用户

发布于 2014-04-27 06:01:23

您可以选择如何实现基于用例的Decorator类。Decorator类不一定要实现相同的接口。

因此,如果您看到Collections.synchronizedCollection.(Collection<T> c),这里有一个静态方法,它充当装饰器,并且没有实现相同的接口。

但是在所示的实现中,这个链接 Decorator类根据用例的需要实现了接口,因为使用了多态性。

因此,它不是强制性的,也没有排斥“是一种”的关系。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/23319746

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档