懒人封装(懒惰模式)
Posted 千锋HTML5大前端
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了懒人封装(懒惰模式)相关的知识,希望对你有一定的参考价值。
- 本文旨在一些特殊的封装上
- 一般会用于处理浏览器兼容性的封装
- 但是看完会对你有一些启发也说不定哦 O(∩_∩)O~
一段简单的代码
- 我们在封装 ajax 请求的时候
- 基于原生 js 的 ajax 代码, 如果考虑到浏览器兼容问题
- 那么我们一定会看到以下几段代码
// 标准浏览器下创建 ajax 对象
new XMLHttpRequest();
// 以下三种都是IE浏览器,对应不同版本
new ActiveXObject('Msxml12.XMLHTTP');
new ActiveXObject('Msxml13.XMLHTTP');
new ActiveXObject('Microsoft.XMLHTTP');
开始第一次封装
想到就做, 我们就来进行一次封装试试看
function xhl_ajax(options)
// ...
let xml = null
if (window.XMLHttpRequest)
xml = new XMLHttpRequest()
else if (new ActiveXObject)
xml = new new ActiveXObject('Microsoft.XMLHTTP')
else
xhl = '你的浏览器可能不支持 ajax 请求, 请更换浏览器再试'
// ...
我这里并没有写完整, 只是简单一个小示例
我们来分析一下这个事情
-
- 我们的判断种类可能有很多种, 比如 A B C D 四种
// 那么这一段代码就变成了
function xhl_ajax()
// ...
if (A)
// ...
else if (B)
// ...
else if (C)
// ...
else if (D)
// ...
else
// ...
// ...
- 代码可能就变成了这个样子
- 可能有的小伙伴会想到, 我改成 策略模式 封装不就好了
我要说的不是这个问题
-
- 不管你改成什么模式封装, 哪怕是起飞模式
- 如果你当前需要匹配到的内容是 D
- 那么每调用一次, 都会从 A 开始判断一次
- 然后到达 D
// 第一次调用
xhl_ajax() // 需要判断 A 不对, B 不对, C 不对, D 对了
// 第二次调用
xhl_ajax() // 需要判断 A 不对, B 不对, C 不对, D 对了
// ...
- 想象一下, 如果调用了 100 次, 那么每次的前三个判断是不是都浪费了呢
- 好像是这样的
- 那我们是不是可以考虑换一个方式来搞一下
懒惰模式封装这段代码
- 我们能不能考虑一下, 我封装完毕的代码, 只有第一次调用的时候会判断
- 后面调用的时候不在判断了, 那么是不是会节省很多呢 ?
- 想到就做
- 原则就是多个事情依次完成
- 前一个成功了, 后面的不做了
- 只要成功过一次, 以后就不在尝试了
- 把我们需要做的几个事情放在几个函数内
function createXHR1 ()
return new XMLHttpRequest;
function createXHR2 ()
return new XActiveXObject("Microsoft.XMLHTTP");
function createXHR3 ()
return new ActiveXObject("Msxml2.XMLHTTP");
function createXHR4 ()
return new ActiveXObject("Msxml3.XMLHTTP");
- 这样一来, 如果第一个能成功, 那么我们调用第一个函数就回得到对应的 ajax 对象了
- 如果第一个不行, 我们就尝试第二个
2. 接下来我们把四个函数放在一个数组内, 遍历依次执行
- 只要找到一个合适的就行了
var xmls = [createXHR1, createXHR2, createXHR3, createXHR4]
let xml = null
for (var i = 0; i < xmls.length; i++)
// 一旦 xml 有内容了, 不再是 null 了, 那么直接结束循环
if (xml) break
// 否则就开始尝试
xml = xmls[i]()
- 问题随之而来了, 如果第一个不对, 那么会报错
- 我的代码就全部挂掉了
- 尝试使用 try catch 解决问题
- 为了不让我的代码挂掉
- 我们改用 try catch 来解决问题
var xmls = [createXHR1, createXHR2, createXHR3, createXHR4]
let xml = null
for (let i = 0; i < xmls.length; i++)
try
xml = xmls[i]()
catch(e)
- 错了也不需要做什么 , 直接下一次就好了
- 看上去挺好, 但是问题依旧没有解决
- 单独制作一个函数
- 我的原则就是, 让这个函数第一次调用和第二次调用不是一个函数就好了
- 也就是我要在第一次调用完毕以后修改这个函数
function createXHR()
// 定义一个 xhr 接收 ajax 对象
// 定义一个 flag 开关,看看是否找到合适的创建 ajax 对象的方法
// 定义一个数组,存储四种创建 ajax 对象的方式
let xml = null,
flag = false,
xmls = [
function ()
return new XMLHttpRequest;
,
function ()
return new ActiveXObject("Microsoft.XMLHTTP");
,
function ()
return new ActiveXObject("Msxml2.XMLHTTP");
,
function ()
return new ActiveXObject("Msxml3.XMLHTTP");
];
// 依旧是循环遍历数组
for (let i = 0, len = xmls.length; i < len; i++)
let curFn = ary[i];
// 依次执行,找到合适的创建 ajax 对象的方法
try
xml = curFn();
// 这里是核心,一旦找到合适的方法,那么我们就把这个函数重新赋值给 createXHR
createXHR = curFn;
// 让开关为 true
flag = true;
break;
catch (e)
// 如果到最后开关依旧为 false,证明四种方法都不合适,那么我们就需要提醒浏览器升级
if (!flag)
throw new Error("your browser is not support ajax, please change your browser,try again!");
// 最后返回 ajax 对象
return xml;
- 看似没有什么改变,但是之一第 28 行的代码,有一个重写 createXHR
- 这个是整个”惰性思想”的核心,也就是说,我只有在当前浏览器中,第一次执行 createXHR 的时候是这个函数
- 一旦找到一个合适的创建 ajax 对象的方法以后,那么从第二次执行 createXHR 开始,就全部都是我们之前数组中的某一个函数了
- 再也不用循环判断,而是直接用一种有效的方法创建一个 ajax 对象了
- 这个是一种 js 中的高级编程思想,如果理解不了,就用我们最开始写的判断的形式来进行就可以,慢慢体会一段时间就能明白了
完整代码
function createXHR()
let xml = null,
flag = false,
xmls = [
function ()
return new XMLHttpRequest;
,
function ()
return new ActiveXObject("Microsoft.XMLHTTP");
,
function ()
return new ActiveXObject("Msxml2.XMLHTTP");
,
function ()
return new ActiveXObject("Msxml3.XMLHTTP");
];
for (let i = 0, len = xmls.length; i < len; i++)
let curFn = ary[i];
try
xml = curFn();
createXHR = curFn;
flag = true;
break;
catch (e)
if (!flag)
throw new Error("your browser is not support ajax, please change your browser,try again!");
return xml;
function xhl_ajax(options)
// ...
const xml = createXHR()
// ...
- 从此以后, 你就去随便调用吧
- 只有第一次的时候会进行判断, 后面的时候都不会进行判断了
- 直接就能使用那个最准确的了
做个真正的贪婪又懒惰开发者
懒人的意思是:外在爱折腾,骨子里懒到极致的开发者。
今天用docker-compose才发现,重启flask,之前自己居然都是不断“在编辑器和控制台来回点鼠标”+按“↑”和“enter”解决的,太“勤快”了(非褒义)!
年纪越大越懒了,懒人才能发现不爽的改进点,才能推动技术进步啊-_-!
1节约看起来不起眼的时间
正经说,每一点小小的改进,只要能稍微节约
“在不同位置点鼠标 +按几个键”的时间,每次节约几秒秒钟,每天、每年下来就能节约很可观的时间了!
这么宝贵的时间可以拿来多睡会觉,想想就很带感啊!
做人一定不能太傻勤快了,因为,往往意味着在时间使用上太大方了(挥霍自己的时间)。
所以,这样往往很穷。
要像庄家在意每一分钱一样,散户要像发财,一定不能傻大方,不在乎,要先学会庄家的思维方式,才有可能最终变成和庄家一样有钱。
有钱是结果,吝啬的思维方式才是原因。
有时间,高效率是结果,懒惰的思维方式才是原因。
2用软件给时间值钱的人省时间
开发软件也是一样。认真去做业务用例组织建模,系统用例,用例规约,交互步骤。要有老大的思维,懒人的思维,阿布的思维,才能发现改进点,改进别人习以为常的工作流,偷点懒。
软件作为服务业,如果能替涉众省点时间,就是体现软件价值的地方。
想靠写软件赚钱最简单的思路,就是给最不缺钱,但是最缺时间(时间最值钱)的人省点时间,然后找他收钱分账。
做软件工程,就是倾听、理解领域专家脑中的领域知识,变成代码,显式表达出来,封装进系统;
做软件开发,就是不断学习配环境、开发、测试、部署各种技巧步骤,变成脚本,显式表达出来,固化进自己的组件库;
不是把具体步骤背进自己脑子,长在自己身上,而是封装在外部脚本,自己及时忘掉具体步骤,但是知道调用什么,能查到,就OK了。
所谓的封装和显示表达,其实本质上就是“用各种书面语进行翻译”的工作。
倾听/审题能力+表达能力 以及更基础的抽象思维(分析)+具象思维(综合)才是真正需要的能力。这是更像是语文的“分析中心思想”的能力,而不是数学计算的能力。
2 前期投入值得吗?
唯一的悖论在这里:为了每次省几秒,结果花了好几天甚至好几星期学新的脚本、语言、工具,值得吗?万一“成本-收益”背不会来呢?
最简单的答案:
stay hungry, stay foolish。
功成不息;坚守痴心。
用到 hungry 的时候,针对的「成功」,也就是「hungry for success」。
虚心叫做「humble」、叫做「be a good listener」、叫做「be open to new ideas」。而 fool,根本不是「虚心的人」,fool 是「笨蛋」的意思。
乔布斯自己的话:
我一直试图做的事情——不断前进。否则,就如迪伦所说,如果你不忙着求生,你就在忙着求死 (If you‘re not busy being born, you‘re busy dying)。
也就是说,不要像过于聪明的智叟一样,算盘打那么精。要像愚公。
但是,总有很多智叟,类似这样的问题永远有人在问一样:
充电电池贵好几倍,万一充不了那么多次,还不如买一次性电池;
太阳能发电那么贵,也省不了几度电,万一半途中坏了,还不如不用;
为了省几小时时间,就花几千亿修高铁,不值
……
其实这有点类似《反脆弱》里塔勒布提出的那个“持续小亏+突然大赚”VS“持续小赚+突然大亏”
计算机技能的学习、健身、养生,买房,都类似基础设施的投资,正相反:
初期尽量“主动有意识多亏点”;然后后面慢慢受益,甚至是无意识,意外受益
大多数人,也算不过这个账。觉得这样不合算,就不干了。
买房比较特殊,要分类讨论:
如果买了房导致每天时间小亏,那还不如不买;
如果当成趸交租金,对抗通胀,那就值得买;
如果既每天小亏时间,但是又对抗通胀,那就要看每天亏的时间能不能用于提高技能,是不是比房价更能有效对抗通胀。不同人答案必然不同。
回到技术问题:不能一开始觉得投入太大,就不投,忍受每天的时间小亏。
作为准备吃技术饭的人,要像个愚公,要有武曲“一心以事业宫紫微为重,其他地方不动心,短虑”的能耐。
短虑,就是foolish的一部分。
发明算命的古人显然是智叟,看不起武曲的短虑,台湾人陈雪涛在《紫微明镜》内外篇里也把武曲说成是“为了事业宫的紫微为重,为了任务而卖命,缺乏大志,不顾亲人感受,财帛是廉贞,只是赚到了精神享受”。——请问,乔布斯难道不正是这样的人吗?
我偏要反过来说:武曲很容易在工作中进入心流状态,也就是所谓的“以事业宫紫微为重,只想着手里的工作,短虑到把其他都忘了”。
此外,贬低喜欢变化、不安分的杀破狼。
——这些都TM是糟粕,纯的。在这个时代,就是要有武曲的傻,和贪狼的贪。
以上是关于懒人封装(懒惰模式)的主要内容,如果未能解决你的问题,请参考以下文章
大道至简---软件工程实践者的思想--------------第二章读后感---是懒人造就了方法