信封问题
有时 很多时候,我需要一个类实现通过使其他类的实例的接口。 听起来很奇怪? 让我给你看一个例子。 在Takes框架中有许多此类,它们的名称都都类似于*Wrap
。 不幸的是,这是一个方便的设计概念,在Java中看起来很冗长。 拥有更短的内容会很棒,例如在EO中。
西北偏北(1959年),阿尔弗雷德·希区柯克(Alfred Hitchcock)
看一下Takes Framework中的RsHtml
。 它的设计看起来像这样(只有一个主要构造函数的简化版本):
class RsHtml extends RsWrap {RsHtml(final String text) {super(new RsWithType(new RsWithStatus(text, 200),"text/html"));}
}
现在,让我们看一下它扩展的RsWrap
:
public class RsWrap implements Response {private final Response origin;public RsWrap(final Response res) {this.origin = res;}@Overridepublic final Iterable<String> head() {return this.origin.head();}@Overridepublic final InputStream body() {return this.origin.body();}
}
如您所见,此“装饰器”除“仅装饰”外不执行任何操作。 它封装了另一个Response
,并通过所有方法调用。
如果还不清楚,我将解释RsHtml
的用途。 假设您有文字,并且想创建一个Response
:
String text = // you have it already
Response response = new RsWithType(new RsWithStatus(text, HttpURLConnection.HTTP_OK),"text/html"
);
您可以使用RsHtml
在许多地方一遍又一遍地完成这种装饰器的组合 :
String text = // you have it already
Response response = new RsHtml(text);
这非常方便,但是RsWrap
非常冗长。 太多的行没有做任何特别的事情。 他们只是将所有方法调用转发到封装的Response
。
我们如何引入一个新概念“ decorators”,并使用一个新关键字decorates
:
class RsHtml decorates Response {RsHtml(final String text) {this(new RsWithType(new RsWithStatus(text, 200),"text/html"))}
}
然后,为了创建一个对象,我们只需调用:
Response response = new RsHtml(text);
装饰器中没有任何新方法,只有构造器。 这些家伙的唯一目的是创建其他对象并封装它们。 它们并不是真正的通用对象。 它们仅帮助我们创建其他对象。
这就是为什么我称它们为“装饰信封”。
这个想法可能看起来与Factory设计模式非常相似,但是它没有静态方法 ,我们试图在面向对象的编程中避免这种方法 。
您可能还会发现这些相关的帖子很有趣: 可组合装饰器与命令式实用工具方法 ; 通过验证装饰器进行防御性编程 ; If-Then-Else是代码气味 ; 垂直和水平装饰 ; 为什么InputStream设计错误 ;
翻译自: https://www.javacodegeeks.com/2017/02/decorating-envelopes.html
信封问题