ip6*_*696 4 java design-patterns decorator
我创建装饰模式示例:
接口:
public interface Printer {
void print(String message);
}
Run Code Online (Sandbox Code Playgroud)
执行:
public class StringPrinter implements Printer {
public void print(String message) {
System.out.println(message);
}
}
Run Code Online (Sandbox Code Playgroud)
和2个装饰者:
将字符串更改为大写:
public class UpCasePrinter implements Printer {
private Printer printer;
public UpCasePrinter(Printer printer) {
this.printer = printer;
}
public void print(String message) {
printer.print(message.toUpperCase());
}
}
Run Code Online (Sandbox Code Playgroud)
打印反向字符串:
public class InversePrinter implements Printer {
private Printer printer;
public InversePrinter(Printer printer) {
this.printer = printer;
}
public void print(String message) {
StringBuilder builder = new StringBuilder(message);
printer.print(builder.reverse().toString());
}
}
Run Code Online (Sandbox Code Playgroud)
一切正常.但在阅读不同网站上的示例时,我发现了不同的实现.extends来自另一个的每个decarator .我看到了实现BufferedInputStream
BufferedInputStream extends FilterInputStream
FilterInputStream extends InputStream
public abstract class InputStream implements Closeable
Run Code Online (Sandbox Code Playgroud)
我无法理解以下内容:
如何创建装饰器有区别吗?至于我 - 装饰器implements与原始类相同的接口或在示例中 - 装饰器extends来自另一个装饰器等链接用于扩展实现
可能在BufferedInputStream的示例中这样的实现只是因为在开始时选择了抽象类而不是接口?
编辑:
换句话说,我不明白有什么用 CarDecorator
LuxerCar并且SportsCar可以implement Car接口和not extends来自CarDecorator.有什么好处?
BufferedInputStream实现方式与您的Car示例完全相同.它装饰了一个InputStream,虽然它是一个抽象类,仍然提供契约,就像接口一样.在这种情况下选择了一个抽象类,因为有些方法具有默认行为(read和skip),并且在编写类时,接口无法支持它(它们现在可以,但
接口中的默认方法稍后添加) .
因为抽象类用于合同,所以BufferedInputStream扩展FilterInputStream,就像CarDecorator实现一样Car.两者都只是代表的简单持有人.它们包含单个protected字段(an InputStream和a Car),并委托对该字段的所有方法调用.这样做的原因是,如果您的合同中有大量方法,则委托每个装饰器中的所有方法可能会导致大量代码重复.当你的界面只有一个方法时,就像你的那样,那么它提供的好处很少.
这当然不是装饰器模式的必要组成部分; 它只是一种稍微不同的实现方式.您的实现仍然是装饰器模式的100%正确实现.