当前位置: 首页 > news >正文

17一起做网店网站php企业网站源码下载

17一起做网店网站,php企业网站源码下载,云南省工程建设交易系统网站,济源网站建设的公司文章目录 3.4 函数式依赖注入技术 Functional injection techniques3.5 模块化依赖注入技术 Modular injection techniques 写在前面 上一篇的最后部分对第三章后续内容做了一个概括性的梳理,并给出了断开依赖项的最简单的实现方案,函数参数值注入法。本…

文章目录

    • 3.4 函数式依赖注入技术 Functional injection techniques
    • 3.5 模块化依赖注入技术 Modular injection techniques

写在前面
上一篇的最后部分对第三章后续内容做了一个概括性的梳理,并给出了断开依赖项的最简单的实现方案,函数参数值注入法。本篇接着介绍函数式注入与模块化注入的具体实现。窃以为后者是本章的难点,需要用心体会作者的设计思路。

(接 上篇 3.3 小节)

3.4 函数式依赖注入技术 Functional injection techniques

函数式实现(FP)与面向对象实现(OOP)并无绝对的优劣之分。FP 固然简洁、清晰、自证性强,但学习曲线陡峭也是不争的事实。

上一节讲到断开外部依赖的一种方案——参数注入法。它通过重构原函数,使其接收一个新参数值(即人为控制的星期索引值)。但这里的参数除了基本类型外,还可以将具体星期值的计算逻辑封装到一个函数内,然后将该函数以参数的形式注入原函数。

于是有了函数式注入的第一套方案——函数作参数注入。对原函数模块 password-verifier-time00.js 作如下更改(L2、L3):

const SUNDAY = 0, SATURDAY = 6;
const verifyPassword3 = (input, rules, getDayFn) => {const dayOfWeek = getDayFn();if ([SATURDAY, SUNDAY].includes(dayOfWeek)) {throw Error("It's the weekend!");}// more code goes here...// return list of errors found..return [];
};

于是单元测试 password-verifier-time00.spec.js 相应变为(L4、L5,以及 L9、L11):

const SUNDAY = 0, SATURDAY = 6, MONDAY = 2;
describe('verifier3 - dummy function', () => {test('on weekends, throws exceptions', () => {const alwaysSunday = () => SUNDAY;expect(() => verifyPassword3('anything', [], alwaysSunday)).toThrowError("It's the weekend!");});test('on week days, works fine', () => {const alwaysMonday = () => MONDAY;const result = verifyPassword3('anything', [], alwaysMonday);expect(result.length).toBe(0);});
});

实测结果:

图 5 改为函数作参数后的实测结果

【图 5 改为函数作参数后的实测结果】

再进一步,可将传入的函数改造为一个高阶函数(high order function,简称 HOF),让依赖注入逻辑与密码校验逻辑分开。这样就有了书中所说的 工厂函数(factory functions) 方案。此时原函数已经被完全改造了。

password-verifier-time00.js

const SUNDAY = 0, SATURDAY = 6;const makeVerifier = (rules, dayOfWeekFn) => {return function (input) {if ([SATURDAY, SUNDAY].includes(dayOfWeekFn())) {throw new Error("It's the weekend!");}const errors = [];// more code goes here..return errors;};
};module.exports = {makeVerifier
};

于是单元测试 password-verifier-time00.spec.js 也要同步更新:

const { makeVerifier } = require('../password-verifier-time00');
const SUNDAY = 0, MONDAY = 1;describe('verifier3 - dummy function', () => {test('factory method: on weekends, throws exceptions', () => {const alwaysSunday = () => SUNDAY;const verifyPassword = makeVerifier([], alwaysSunday);expect(() => verifyPassword('anything')).toThrow("It's the weekend!");});test('on week days, works fine', () => {const alwaysMonday = () => MONDAY;const verifyPassword = makeVerifier([], alwaysMonday);const result = verifyPassword('anything');expect(result.length).toBe(0);});});

实测结果同上面的 图 5。这样做的好处,就是让校验的配置独立于校验的执行,在减少原函数参数个数的同时,测试用例的可读性也更强。一举多得。

3.5 模块化依赖注入技术 Modular injection techniques

这一节开始加大难度了,主要目的在于让大家感受一下模块化注入的繁琐。为什么会这么繁琐呢?因为以模块的方式注入依赖项虽然写起来很爽,但对于单元测试而言完全是另一码事。回到最开始的原函数版本——

password-verifier-time00.js

const moment = require("moment");
const SUNDAY = 0, SATURDAY = 6;const verifyPassword = (input, rules) => {const dayOfWeek = moment().day();if ([SATURDAY, SUNDAY].includes(dayOfWeek)) {throw Error("It's the weekend!");}// more code goes here...// return list of errors found..return [];
};module.exports = {verifyPassword,
};

怎样从单元测试的角度断开上述代码中的直接依赖呢?答案是没有现成的方法,只能“曲线救国”。这就要用到 3.2 节补充的 Seam 缝隙的概念了:通过构造一个特定的写法,以便将直接依赖项替换成单元测试能够直接干预的代码,实现 控制反转

以下代码给出了一个示例版本:

核心重构1:根据模块化注入方案重构的新版待测函数示例

const originalDependencies = {moment: require('moment')
};let dependencies = { ...originalDependencies };const inject = (fakes) => {Object.assign(dependencies, fakes);return function reset () {dependencies = { ...originalDependencies };};
};const SUNDAY = 0; const SATURDAY = 6;const verifyPassword = (input, rules) => {const dayOfWeek = dependencies.moment().day();if ([SATURDAY, SUNDAY].includes(dayOfWeek)) {throw Error("It's the weekend!");}// more code goes here...// return list of errors found..return [];
};module.exports = {SATURDAY,verifyPassword,inject
};

相比其他小节,上述代码是本章最难的一段。原因很简单——我之前从没这样认真研究过(​开个玩笑​ 😆)。

先来仔细看看这段代码。为了成功断开由 moment.js 引入的直接依赖,需要构造一个新的写法,即第 17 行中的星期值生成逻辑:

// 改造前:
const dayOfWeek = moment().day();
// 改造后:
const dayOfWeek = dependencies.moment().day();

先甭管 dependencies 怎么定义的,写成第 4 行的形式后,最初的 moment().day() 就变成了 dependencies 下的 moment() 方法;这时,只要再设计一个注入逻辑(比如第 7 至 12 行的 inject(fakes) 函数),并让它在运行测试时对 dependencies.moment 属性 重新赋值,这样就实现了原始依赖 moment 模块的平替,从而实现 控制反转;最后,为了不破坏原函数逻辑,等到单元测试结束,还得再设计一套 重置逻辑,让 dependencies.moment 重新指向 moment 模块。这就是模块化注入的大致流程。

与之配套的单元测试代码如下:

核心代码2:模块化改造后的新校验函数在单元测试模块中的应用示例

const { inject, verifyPassword, SATURDAY } = require('../password-verifier-time00');const injectDate = (newDay) => {const reset = inject({moment: function () {// we're faking the moment.js module's API here.return {day: () => newDay};}});return reset;
};describe('verifyPassword', () => {describe('when its the weekend', () => {it('throws an error', () => {const reset = injectDate(SATURDAY);expect(() => verifyPassword('any input')).toThrowError("It's the weekend!");reset();});});
});

第一次看这两段代码,头是真的晕。比如上面的高阶函数 injectDate():它接收一个普通的星期值 newDay,然后用这个值构造了一个测试专用的伪对象 fakes(示例中没有单独声明)并直接传入 inject() 方法,最后将执行结果——即包含重置逻辑的 reset() 函数——作为函数结果返回。最后在测试用例的第 18 行和第 23 行实现了控制的反转与依赖项的重置。

抱着将信将疑的心理,我在本地实测了上述代码,居然真的可以这样写:

图 6 按照模块化注入方案重构原函数得到的实测结果

【图 6 按照模块化注入方案重构原函数得到的实测结果】

正当我惊叹于作者对 JavaScript 闭包的深入理解时,大佬又再次复盘上述写法,对比了该方案的优劣:

  • 优势:解决了最开始的直接依赖问题,使用时也相对比较简单(按大佬的说法,多写几遍自然就有感觉了……);
  • 劣势:即闭包 dependencies 中的 moment 属性与依赖的 moment 模块之间未能实现解耦。遇到真实项目测试就傻眼了:成千上万个依赖项接口难不成还得挨个重构成特定的闭包属性?

为此,作者给出了如下建议:

  1. 永远不要在代码中直接使用第三方依赖,最好加一个适配层缓冲一下,这样就不怕第三方库修改接口或者更换其他依赖项了。
  2. 慎用这个天坑的模块注入方案,换成其他实现方案,比如之前介绍的视函数为参数、或者函数柯里化;或者后面紧接着会介绍的 构造函数 以及 接口 的解决方案。

总之,这一节主要是给后续的高级方案做铺垫用的;对我而言也是增长见识的一节,让我知道设计模式中的适配器模式在单元测试中原来还能这么用。

http://www.yayakq.cn/news/598947/

相关文章:

  • 怎样建立网站绍兴网站建设企业
  • eclipse做网站代码互联网行业都有哪些工作岗位呢
  • 国外优秀的html5网站wordpress怎么加地图吗
  • 珠三角网站建设wordpress会员系统
  • 莆田 网站建设广东手机网站建设报价
  • 国内精品网站建设泗洪做网站公司
  • 解决国外网站很慢wordpress用户验证失败
  • 几百块钱可以做网站吗iis7.0搭建网站
  • 成品网站w在线观看免费开源的个人网站系统
  • 建网页放到什么网站上广西茶叶网站建设
  • 做我的狗漫画网站企业网站建设公司怎么做
  • 自己网站建设做阿里巴巴英文网站
  • 公司网站制作有哪些注意事项国外设计网站pinterest网址
  • 温州网站建设方案推广动态数据库网站
  • 怎么搭建钓鱼网站杭州企业网站定制
  • 个体可以做几个网站黄金软件免费下载
  • 个人网站备案icp制作网页难吗
  • 怎么做类似清风dj网站wordpress 作品集网站
  • 深圳外贸网站搭建国内有做外汇的正规网站吗
  • 网站开发需要文章写的好吗石狮app网站开发
  • 境外网站海口市住房和城乡建设局网站
  • asp 网站源码南京百度关键字优化价格
  • 专业做家居的网站有哪些专业做家电经销的网站
  • 广东网站建设建站模板个人网站制作论文
  • 浅谈中兴电子商务网站建设深圳宝安住房和建设局网站
  • 东莞网站推广哪里好建设网站技术公司电话号码
  • 文章网站建设东莞横沥网站制作
  • wordpress 微站适合权重小的网站做的专题
  • 商务型网站有哪些装潢公司网站设计与制作
  • 戴南网站建设网站建设合同doc