外观模式

外观模式是一种很简单的模式,它只是为对象提供了更多的可供选择的接口。使方法保持短小而不是处理太多的工作是一种很好的实践。在这种实践的指导下,你会有一大堆的方法,而不是一个有着非常多参数的uber方法。有些时候,两个或者更多的方法会经常被一起调用。在这种情况下,创建另一个将这些重复调用包裹起来的方法就变得意义了。

例如,在处理浏览器事件的时候,有以下的方法:

  • stopPropagation()

    阻止事件冒泡到父节点

  • preventDefault()

    阻止浏览器执行默认动作(如打开链接或者提交表单)

这是两个有不同目的的相互独立的方法,他们也应该被保持独立,但与此同时,他们也经常被一起调用。所以为了不在应用中到处重复调用这两个方法,你可以创建一个外观方法来调用它们:

  1. var myevent = {
  2. // ……
  3. stop: function (e) {
  4. e.preventDefault();
  5. e.stopPropagation();
  6. }
  7. // ……
  8. };

外观模式也适用于一些浏览器脚本的场景,即将浏览器的差异隐藏在一个外观方法下面。继续前面的例子,你可以添加一些处理IE中事件API的代码:

  1. var myevent = {
  2. // ……
  3. stop: function (e) {
  4. // 其它浏览器
  5. if (typeof e.preventDefault === "function") {
  6. e.preventDefault();
  7. }
  8. if (typeof e.stopPropagation === "function") {
  9. e.stopPropagation();
  10. }
  11. // IE
  12. if (typeof e.returnValue === "boolean") {
  13. e.returnValue = false;
  14. }
  15. if (typeof e.cancelBubble === "boolean") {
  16. e.cancelBubble = true;
  17. }
  18. }
  19. // ……
  20. };

外观模式在做一些重新设计和重构工作时也很有用。当你想用一个不同的实现来替换某个对象的时候,你可能需要花相当长一段时间才能完成(一个复杂的对象),与此同时,一些使用这个新对象的代码也在被同步编写。你可以先想好新对象的API,然后在旧的对象前面使用新的API创建一个外观方法。使用这种方式,当你完全替换掉旧的对象的时候,你只需要修改少量的调用代码,因为新的代码已经是在使用新的API了。