适合用设计模式解决的问题场景

在曾探的《Javascript设计模式与开发实践》中,有这样一段话:

设计模式在很多时候其实都体现了语言的不足之处。Peter Norvig 曾说,设计模式是对语言不足的补充,如果使用设计模式,不如去找一门更好的语言。这句话非常正确。

而在我看来,语言未必要封装设计模式,设计模式也不必须封装在语言内部。设计模式并不完全是语言不足的补充,而是一种不分语言针对特定问题的通用性解决方案。

我在研究生阶段曾经研究过过去五年的统考数学试卷。得出的结论是试卷的考题分布是有规律的。数学一共21道题(现在不知道了),分别来自高数、概率论和数理统计。

通过分析过去五年试卷:国家教育部考试司仁慈,每个位置的题目,大概来自那本书其实也是明确的,三科分别可能出现的题目个数也是确定的。

然后就是一定量的题海战术,研究试卷里面出现的考试题目,研究考试题目的变种。我把多个变种题目分析之后,得出一道母题,母题是相对的,表征这是一类题目。一类题目也就有相似的解决方案。

言归正传,回到设计模式,我认为需要设计模式解决的开发场景一定是具有代表性的,是有一定难度的。而开发这件事总体有难度的场景其实是有限的,因为对于有边界的事情我认为都是有限的,业务开发肯定是有限的。

因为有限,总结其中代表性的,常见的问题场景就很必要。搞懂这些之后,可以更加专注于开发的难点或者核心点。

当然常见的问题场景未必需要设计模式解决。但这回只说需要用设计模式解决的场景。

  1. 全局只需要一个这样的东西,比如全局只有一个window,全局缓存对象,登录页面的登录窗口……
  • 这个时候用单例模式解决,单例模式的通用模式
var getSingle = function( fn ){ 
    var result; 
    return function(){ 
       return result || ( result = fn .apply(this, arguments ) ); 
    } 
}; var getSingle = function( fn ){ 
    var result; 
    return function(){ 
       return result || ( result = fn .apply(this, arguments ) ); 
    } 
}; 

2,多个if else怎么重构?简单的用策略模式

 
// 原来
      function ifbox(type){
        if(type === 'a'){
          return 1
        }
        if(type === 'b'){
          return 2
        }
        if(type === 'c'){
          return 3
        }
      }
      //
      function ifbox(type){
        var obj = {
          a: 1,
          b: 2,
          c: 3
        }
        return obj[type]
      }

复杂的用迭代器模式

 
 // 原来
      function ifbox2(){
        // type, num 为全局变量
        if(type === 'a' && num === 10){
          return 1
        }
        if(type === 'b' && num === 11){
          return 2
        }
        if(type === 'c' && num === 12){
          return 3
        }
      }
      //
      function ifbox2(){
        var ten = function (){
          if(type === 'a' && num === 10){
             return 1
          } 
        }
        var eleven = function (){
          if(type === 'a' && num === 11){
             return 1
          } 
        }
        var twelve = function (){
          if(type === 'a' && num === 12){
             return 1
          } 
        }

        return [ten, eleven, twelve]
      }
      // 使用
      const arr = ifbox2()
      const len = arr.length
      for (let i = 0; i < len; i++) {
        if (arr[i]()) {
          return arr[i]()
        }
      }

3,图片懒加载以及接口缓存?

  • 用代理模式,出于各种原因当一个对象不方便直接访问另一个对象时候,找个中间人来操作达到某个目的,举一个缓存代理
先创建一个用于求乘积的函数: 
var mult = function(){ 
 console.log( '开始计算乘积' ); 
 var a = 1; 
 for ( var i = 0, l = arguments.length; i < l; i++ ){ 
 a = a * arguments[i]; 
 } 
 return a; 
}; 
mult( 2, 3 ); // 输出:6 
mult( 2, 3, 4 ); // 输出:24 
现在加入缓存代理函数:
var proxyMult = (function(){ 
 var cache = {}; 
 return function(){ 
 var args = Array.prototype.join.call( arguments, ',' ); 
 if ( args in cache ){ 
 return cache[ args ]; 
 } 
 return cache[ args ] = mult.apply( this, arguments ); 
 } 
})(); 
 proxyMult( 1, 2, 3, 4 ); // 输出:24 
 proxyMult( 1, 2, 3, 4 ); // 输出:24

4,当功能代码的使用者和开发者不是一个人时候

  • 用观察者模式或者发布订阅模式
var salesOffices = {}; // 定义售楼处
salesOffices.clientList = {}; // 缓存列表,存放订阅者的回调函数
salesOffices.listen = function( key, fn ){ 
 if ( !this.clientList[ key ] ){ // 如果还没有订阅过此类消息,给该类消息创建一个缓存列表
 this.clientList[ key ] = []; 
 } 
 this.clientList[ key ].push( fn ); // 订阅的消息添加进消息缓存列表
}; 
salesOffices.trigger = function(){ // 发布消息
 var key = Array.prototype.shift.call( arguments ), // 取出消息类型
 fns = this.clientList[ key ]; // 取出该消息对应的回调函数集合
 if ( !fns || fns.length === 0 ){ // 如果没有订阅该消息,则返回
 return false; 
 } 
 for( var i = 0, fn; fn = fns[ i++ ]; ){ 
 fn.apply( this, arguments ); // (2) // arguments 是发布消息时附送的参数
 } 
}; 
salesOffices.listen( 'squareMeter88', function( price ){ // 小明订阅 88 平方米房子的消息
 console.log( '价格= ' + price ); // 输出:2000000 
}); 
salesOffices.listen( 'squareMeter110', function( price ){ // 小红订阅 110 平方米房子的消息
 console.log( '价格= ' + price ); // 输出:3000000 
}); 
salesOffices.trigger( 'squareMeter88', 2000000 ); // 发布 88 平方米房子的价格
salesOffices.trigger( 'squareMeter110', 3000000 ); // 发布 110 平方米房子的价格

先总结这几个。后面两个例子代码直接使用了书中的。

我站在山顶看风景!下面是我的家乡!
原文地址:https://www.cnblogs.com/zhensg123/p/14669693.html