3-4 模式的实际运用
本节编程练习不计算学习进度,请电脑登录imooc.com操作

模式的实际运用

在进行组件开发中,为了保证组件可以在不同的类似项目场景中都能适用,那么就必须是对其常用功能抽象出来加以实现。

我们来看看具体的实际用处:

假设一段ajax的请求,成功后通过done返回结果数据:

$.ajax({
  url: "test.html",
  context: document.body
}).done(function(data) {
  //data数据的处理
  $('aaron1').html(data.a)
  $('aaron2').html(data.b)
  $('aaron3').html(data.c)
  //其余处理
});

咋一看好像都挺好,没什么问题,但是仔细观察我们会发现所有的逻辑是不是都写在done方法里面,这样确实是无可厚非的,但是问题就是逻辑太复杂了。Done里面有数据处理、html渲染、还可能有其它不同场景的业务逻辑。这样如果是换做不同的人去维护代码,增加功能就会显得很混乱而且没有扩展性。那么观察者模式能很好的解决了这个的问题。

我们优化下代码:

$.ajax({
  url: "test.html",
  context: document.body
}).done(function(data) {
    pocessData()
    pocessHtml()
    pocessOther()
  }

  function pocessData() {
    //处理数据
  }

  function pocessHtml() {
    $('aaron1').html(data.a)
    $('aaron2').html(data.b)
    $('aaron3').html(data.c)
  }

  function pocessOther() {
    //处理其他逻辑
  }

这种方式的好处是,分离出各种的业务函数,从而降低了代码之间的耦合度,但是这样代码写法几乎就是“就事论事”的处理,达不到抽象复用。

那么我们用之前的观察者模式加工一下上面的代码:(这只是伪代码,用于理解)

Observable.add(function() {
  //pocessData
})

Observable.add(function() {
  $('aaron1').html(data.a)
  $('aaron2').html(data.b)
  $('aaron3').html(data.c)
})

Observable.add(function() {
  //pocessOther
})

$.ajax({
  url: "test.html",
  context: document.body
}).done(function(data) {
  Observable.fire(data)
})

设计该模式背后的主要动力是促进形成松散耦合。在这种模式中,并不是一个对象调用另一个对象的方法,而是一个对象订阅另一个对象的特定活动并在状态改变后获得通知。订阅者也称为观察者,而被观察的对象称为发布者或主题。当发生了一个重要的事件时,发布者将会通知(调用)所有订阅者并且可能经常以事件对象的形式传递消息。

总的来说,观察者模式所做的工作就是在解耦,让耦合的双方都依赖于抽象,而不是依赖于具体。从而使得各自的变化都不会影响到另一边的变化。

任务

  1. <!DOCTYPE HTML>
  2. <html>
  3. <head>
  4. <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  5. <script src="http://img1.sycdn.imooc.com//down/540812440001e40e00000000.js" type="text/javascript"></script>
  6. <script src="http://img1.sycdn.imooc.com//down/541f6ff70001a0a500000000.js" type="text/javascript"></script>
  7.  
  8. <title></title>
  9. </head>
  10. <body>
  11.  
  12.  
  13. <script type="text/javascript">
  14.  
  15.  
  16. var Observable = {
  17. callbacks: [],
  18. add: function(fn) {
  19. this.callbacks.push(fn);
  20. },
  21. fire: function(data) {
  22. this.callbacks.forEach(function(fn) {
  23. fn(data);
  24. })
  25. }
  26. }
  27.  
  28.  
  29. function ajax(arg){
  30. setTimeout(function(){
  31. arg.successful(arg.data+ ',返回获取到后台的数据')
  32. },1000)
  33. }
  34.  
  35. //使用add开始订阅:
  36. Observable.add(function(data) {
  37. show('执行动作一 ' + data)
  38. })
  39. Observable.add(function(data) {
  40. show('执行动作二')
  41. })
  42.  
  43.  
  44. //一段ajax请求,成功后处理
  45. ajax({
  46. data:'请求数据',
  47. successful:function(data){
  48. Observable.fire(data); //触发动作
  49. }
  50. })
  51.  
  52.  
  53.  
  54. </script>
  55. </body>
  56. </html>
下一节