设计模式之装饰者模式

设计模式:装饰者模式

装饰者模式是不太常用的一种设计模式。我不太明白为什么它没能流行起来,虽然它用起来很方便。装饰者模式让你能够在可控的范围内往一个对象添加功能。这个在运行时也是靠谱的,甚至在静态类型的语言里也是如此。装饰者模式可以当作子类的一个替代品。子类化在编译期的时候添加新的特性,这个改动影响到原始类的所有实例;装饰者模式能在运行时给指定的对象提供新的行为。它是坚持开闭原则的一个很好的工具。

下面的一些例子将让它看到这种模式的魅力:

示例1:HTTP认证

假设这里有个HTTP客户端 ,它访问的是一个RESTful的服务。

服务有一部分是能直接访问的,有一些则需要用户进行登录。当客户端试图访问一个受限资源的时候,这个RESTful服务会返回一个401未授权的响应码。

修改客户端让它处理401的话会带来浪费,因为每个调用都有可能需要认证。我们应该把认证代码剥离出来。剥离到哪儿呢?

现在是装饰者模式出场的时候了:

public intpublic class AuthenticatingHttpClient

implements HttpClient {

private final HttpClient wrapped;

public AuthenticatingHttpClient(HttpClient wrapped) {

this.wrapped = wrapped;

}

@Override
public Response execute(Request request) {
Response response = wrapped.execute(request);
if (response.getStatusCode() == 401) {
authenticate();
response = wrapped.execute(request);
}
return response;
}

protected void authenticate() {
// …
}

}
现在REST客户端不用再操心认证的事了,这个由AuthenticatingHttpClient来擦屁股。

示例2:缓存授权决策
好的,现在用户登录进来了,REST服务器也知道了他的身份。它来决定谁能访问某个资源,谁不能。

也就是说,它得实现用户认证,比如使用XACML。这样的话,需要有一个策略决策点(PDP,Policy Decision Point)来处理请求。

权限检查通常开销都很大,尤其当权限粒度变得很细并且访问策略很复杂的时候。访问策略通常不会频繁变更,因此很适合缓存起来。

这是装饰者模式另一个很适合的场景:

public class CachingPdp implements Pdp {

private final Pdp wrapped;

public CachingPdp(Pdp wrapped) {
this.wrapped = wrapped;
}

@Override
public ResponseContext decide(
RequestContext request) {
ResponseContext response = getCached(request);
if (response == null) {
response = wrapped.decide(request);
cache(request, response);
}
return response;
}

protected ResponseContext getCached(
RequestContext request) {
// …
}

protected void cache(RequestContext request,
ResponseContext response) {
// …
}

}
这个代码和第一个例子很像,这也是为啥叫它装饰者模式的原因。

从这两个例子里相信你也猜到了,装饰者模式非常适合用在横切关注点,比如认证的安全特性,授权,审计,当然它能派上用场的地方远不止这些。

如果你上点心的话,我相信你一定会发现更多适合这个模式的场景。

原文链接

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值