设计模式之外观模式

定义

为子系统中的一组接口提供一个一致的界面,外观模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。

结构

设计模式之外观模式
  • 模块,接受Facade的委派,真正实现功能。
  • Facade,定义子系统的多个模块对外的高层接口,通常需要调用内部多个模块,将客户端的请求委派给适当的模块。

简单实现

模块A

public class AModule {

  public void testA() {
    System.out.println("this is A module");
  }
}

模块B

public class BModule {

  public void testB() {
    System.out.println("this is B module");
  }
}

外观类

public class Facade {

  private AModule aModule;
  private BModule bModule;

  public Facade() {
    this.aModule = new AModule();
    this.bModule = new BModule();
  }

  public void test() {
    aModule.testA();
    bModule.testB();
  }
}

客户端

public class Client {

  public static void main(String[] args) {

    Facade facade = new Facade();
    facade.test();
  }

}

客户端和外观类交互,不需要知道子系统中模块的存在。

外观模式在Tomcat中的实现

Tomcat中的RequestFacade的实现

/**
 * Facade class that wraps a Coyote request object.
 * All methods are delegated to the wrapped request.
 *
 * @author Craig R. McClanahan
 * @author Remy Maucherat
 */
@SuppressWarnings("deprecation")
public class RequestFacade implements HttpServletRequest {

    /**
     * Construct a wrapper for the specified request.
     *
     * @param request The request to be wrapped
     */
    public RequestFacade(Request request) {

        this.request = request;

    }

    @Override
    public Object getAttribute(String name) {

        if (request == null) {
            throw new IllegalStateException(
                            sm.getString("requestFacade.nullRequest"));
        }

        return request.getAttribute(name);
    }
}

客户端只需要和RequestFacade交互,不需要知道具体的实现Request类。

优缺点总结

优点

  1. 对客户端屏蔽了子系统的实现,子系统更加容易扩展和维护。
  2. 对客户端来说更加的简单易用,不需要了解子系统内部的实现。

缺点

  1. 过多的或者不合理的外观模式容易让人迷惑,到底是和Facade交互好还是直接和子系统交互好。

本质

外观模式的本质就是封装交互,简化调用。外观模式很好的体现了 最少知识原则,客户端只需要知道外观类,可以在不影响客户端的情况下,实现系统内部的维护和扩展。
我们项目中的service类中调用多个dao层的接口来实现功能,service类也可以看做外观模式的实现。

使用场景

  1. 想要为复杂的子系统提供一个简单的接口。
  2. 客户端和多个子系统存在耦合,引入外观类来解耦。

参考

大战设计模式【10】—— 外观模式
设计模式的征途—11.外观(Facade)模式
研磨设计模式-书籍

上一篇:设计模式7 - 门面模式【Facade Pattern】


下一篇:PureMVC 模块的划分