gpt4 book ai didi

java - 违反is-a关系的装饰器设计模式

转载 作者:搜寻专家 更新时间:2023-10-31 20:34:21 26 4
gpt4 key购买 nike

我最近开始研究装饰器设计模式,但我有一个疑问。装饰器实现与它们试图装饰的组件相同的接口(interface)。这不违反 is-a 关系吗?而且既然装饰器有组件(通过组合),为什么真的需要装饰器实现与具体组件实现相同的组件接口(interface)。?

看了Headfirst上的装饰器设计模式,感觉装饰器可以直接实现组件。装饰器不需要抽象类/接口(interface)。

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

最佳答案

了解码合和装饰器之间的区别很重要。 Decorator 是一种组合形式,但它的主要区别在于它以一种方式让通常使用装饰对象的代码使用包装器。

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

public static void copy(InputStream in, OutputStream out) { ... }

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

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

好吧,我可以创建扩展 FileInputStreamCountingFileInputStreamCountingFileInputStream 是一个 FileInputStream。但是,如果明天我需要为 SocketInputStream 做同样的事情怎么办?我必须创建一个扩展 SocketInputStreamCountingSocketInputStream

我可以改用组合!我可以创建一个类,它采用 InputStream 并计算读取到它的字节数:

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 is-not-an InputStream .

所以这就是 Decorator 的用武之地。我们可以制作一个 CountingInputStream。两者都实现了 InputStream(因此 is-an InputStream)并委托(delegate)给另一个 InputStream。这样我们就可以在我们的 copy() 方法中使用它。

简而言之,就是一个关系而言,CountingInputStream是一个InputStream(这通常是我们所关心的) 但它不是 FileInputStream,这允许它包装任何 InputStream,如 LimitInputStream这是装饰 DeflaterInputStream这是装饰 BufferedInputStream这是装饰 FileInputStream .归根结底,copy() 不需要关心!

关于java - 违反is-a关系的装饰器设计模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23319746/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com