zoukankan      html  css  js  c++  java
  • 设计模式之装饰者模式

    设计模式:装饰者模式

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

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

    示例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) {
        // ...
      }
      
    }
    

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

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

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

    原文链接

  • 相关阅读:
    Thinkphp3.2 cms之角色开发
    说几个你知道的设计模式?
    9种实现点击一个链接弹出一个小窗口的代码
    分享自己作为一个程序员的找工作经历
    网页设置锚点
    博客园网摘地址
    PHP面试总结
    简单的10秒倒计时
    PHP测试题目
    关键字搜索内容总结
  • 原文地址:https://www.cnblogs.com/chenying99/p/3597710.html
Copyright © 2011-2022 走看看