敲碎时间的人的个人专栏

js设计模式(工厂,原型,单例)

我们知道,在设计模式中,创建型模式有五种,今天我们继续讨论剩下的模式。 工厂模式工厂的作用是生产具有相同特性的相似物体。这有助于轻松管理、维护和操作对象。例如,在我们的玩具工厂,每个玩具都会有一定的信息。它将包含购买日期、原产地和类别。这里我首先定义了一个玩具叫做StarWars,然后定义了一个玩具工厂,然后根据工厂函数创建一个具体的玩具。 var StarWars = fun
阅读更多

js设计模式(抽象工厂和建造器)

什么是设计模式首先,需要了解设计模式的真正定义。作为软件开发人员,您可以“以任何方式”编写代码。但是,设计模式将是最佳实践,这将对您维护代码的方式产生重大影响。以最大的技巧编写的代码将比业余代码持续更长时间。这意味着当您选择正确的编码风格时,您无需担心可扩展性或维护。设计模式的作用是帮助您构建不会使整体问题复杂化的解决方案。模式将帮助您构建交互式对象和高度可重用的设计。设计模式是面向对象编程中不可
阅读更多

耦合

耦合上一节我们重点关注了扇出的内容,以及用例子说明了如何才能将一个函数或者模块的代码通过重构来达到一个合理的扇出值。今天我们来理解耦合:耦合是关注模块如何组合在一起的,增加子模块或许可以减少扇出的值,但是不能减少原始模块对最初依赖之间的耦合度;本质是将显示依赖变成了间接依赖。虽然今天我们不讲解内聚,但是我们也说说什么是内聚,以及什么是耦合? 内聚是从功能角度来度量模块内的联系,一个好的内
阅读更多

圈复杂度

圈复杂度圈复杂度是表示代码中独立现行路径的数量。举个例子:function sum(a, b) { if (typeof(a) !== typeof(b)) { throw new Error('Cannot sum different types'); } else { return a + b; } }这个方法的圈复杂度就是2,也就是说需要测试两个分支,
阅读更多

函数的命令和查询分裂

上一节,我们知道了什么是命令,以及什么是查询。今天我们继续前面的例子,来试着将一个功能太多的函数进行命令和查询的分离。      /** * 查询函数(用于设置值并返回) * */ function configure(values) { var config = { docRoot: '/somewhere' }; var
阅读更多

什么是可测试代码

什么是可测试代码我们理解的可测试代码指的是:1、松耦合2、短小的3、可隔离的我们会依照这三个原则来分析,怎么样编写可测试的代码?一般来说,一个函数或者一个功能,如果越复杂,那么实现此功能需要的代码可能就会越多,代码量就会越多,出现潜在Bug的概率就越大。因此,编写可测试代码的第一步就是让函数或者功能保持最小代码量,而保持最小代码量的方法就是让命令(Command)和查询(Query)分离。我们首先
阅读更多

sinon最佳实践

我们对可测试js代码的学习已经有了一些理解,也认识了一些关于测试替身的问题,比如什么时候使用spies?什么时候使用stubs,什么时候使用mocks。今天我们用一个测试框架sinonjs来做具体的说明介。简介测试使用了Ajax、网络、超时、数据库或其他依赖项的代码可能很困难。例如,如果您使用 Ajax 或网络,您需要有一个服务器来响应您的请求。使用数据库,您需要使用测试数据设置测试数据库。所有这
阅读更多

Injector框架理解(九)

上一节我们学习了关于didi依赖注入框架的关于组件和加载器作用域相关的使用,今天我们来了解一些初始化的一些使用。我们还是用一些例子来说明问题const { Injector } = require('didi'); const { expect } = require('chai'); const injector = new Injector([ { __init__: [ 'foo' ]
阅读更多

Injector框架理解(一)

在可测试js的框架学习过程中,我们不断提到了依赖注入,依赖注入使用最多的就是在java中的spring,为了在js中使用依赖注入,我们今天学习另一个不那么常用的框架:didi首先看看安装命令npm install didi这个时候,我看到项目下的package.json{ "name": "babelwebpack", "version": "1.0.0", "description"
阅读更多

Injector框架理解(八)

上一节我们学习了didi框架如何使用子加载器加载子模块的一些知识,还有包括初始化一些基本组件,今天我们继续学习相关的知识,还是从一个例子开始。const { Injector } = require('didi'); const { expect } = require('chai'); const injector = new Injector([ { __exports__: [ 'foo
阅读更多

Injector框架理解(七)

上一节我们学习了didi依赖注入框架如何创建子加载器,以及如何加载子模块,今天我们继续使用例子来说明相关的内容:我们首先看看如下的例子:const {Injector} = require('didi'); const injector = new Injector([ { __exports__: [ 'foo' ], 'foo': [ 'fact
阅读更多

Injector框架理解(六)

上一节我们学习了didi依赖注入框架,如何使用模块,以及如何创建子依赖注入器,今天我们继续深入理解它们,先来看看第一个例子: const {Injector} = require('didi'); //定义一个父模块 const moduleParent = /** @type ModuleDeclaration */ ({ a: [ 'value', 'a-parent' ]
阅读更多

深入理解Mock,Stub

深入理解Mock,Stub前面我们学习了Mock,Stub的一些基础知识,今天我们深入理解一下:我们知道,单元测试最重要的工作就是破除依赖项(break dependency),破除依赖的技巧有好几个,如何使用这些技巧也是我们需要深入研究和学习的。首先需要指出的是破除依赖项的技巧有Mock类和Stub类。为了破除依赖项它们都可以说是伪造相关library界面的假物件,只是用途不一样而已:Stub:
阅读更多

Fakes,Mocks,Stubs的区别

Fakes,Mocks,Stubs的区别首先,本节的内容有一点偏理论,而且代码也不一定是用js来说明的,其次,理论的作用在于指导实践,因此我们后期的可测试js很多代码都会用到今天的理论知识,好了,开始吧。1、FakeFakes are objects that have working implementations, but not same as production one. Usually
阅读更多

Injector框架理解(五)

上一节我们学习了如何配置一个组件的依赖项,以及怎么配置属性组件,还有就是invoke方法的使用,今天我们继续学习依赖注入框架的另外一些知识,比如如何初始化组件。我们先来看看instantiate方法:const {Injector}= require('didi'); class Foo { constructor(abc1, baz1) { this.abc = abc1;
阅读更多

Injector框架理解(四)

上一节我们学习了配置一个组件的依赖项的两种方式,以及配置一个属性组件;今天我们来学习didi框架的另外一些功能,我们先看看代码:const {Injector} = require('didi'); function bar(baz, abc) { return { baz: baz, abc: abc }; } bar.$inject = [ 'baz',
阅读更多

Injector框架理解(三)

上一节我们学习了didi框架的如何重用一个模块,以及依赖注入的数组式配置,今天我们继续学习如何配置依赖注入等。我们还是通过例子来说明使用方法const {Injector} = require('didi'); class FooType { constructor() { this.name = 'foo'; } } function barFactory(foo
阅读更多

js设计模式(中介-Mediator)

中介设计模式另一个设计模式,正如其名称所暗示的那样,是中介,起着调解作用。这种模式为一组对象提供了一个中心控制点。它被大量用于状态管理。当其中一个对象更改其属性的状态时,中介可以轻松地将其广播给其他对象。下面是一个简单的例子,说明 Mediator 设计模式如何提供帮助:var Participant = function (name) { this.name = name; th
阅读更多

有趣的web-console

有趣的web-consoleWeb 控制台是一种工具,主要用于记录与网页相关的信息,例如:网络请求、JavaScript、安全错误、警告、CSS 等。它使我们能够通过在页面内容中执行 JavaScript 表达式来与网页交互。log()error()warn()clear()time() and timeEnd()table()count()group() and groupEnd()custom
阅读更多

Injector框架理解(二)

今天我们继续学习didi这个依赖注入框架,上一节我们知道了怎么定义组件,怎么定义模块,怎么通过Injector这个类来载入模块和获取组件。今天我们来学习如何重用模块:我们首先定义好组件和模块:const {Injector} = require('didi'); class FooType { constructor() { this.name = 'foo'; } }
阅读更多

EventStorming

EventStorming 词汇表和备忘单EventStorming 是超越孤立边界最智能的协作方法。EventStorming的能力来自多元化、多学科的人群,他们共同拥有丰富的智慧和知识。它最初是为领域驱动设计聚合建模的研讨会发明的,但它现在具有更广泛的适用范围。从获得整个领域的全局问题空间到深入了解整个软件交付流程并制定长期规划。这些研讨会中的每一个都有相同的基本要求和需求。在这里,您将找到以
阅读更多

什么是单元测试

什么是单元测试有没有遇到过类似的情况,当你打算开始写出高质量的代码,为了写出高质量的代码,公司的大牛告诉你,写好单元测试是高质量代码的基石。然后你每次写完功能代码,总是给每个方法写大量的单元测试,然后请教大牛,没想到大牛冷冷的说一句:你写的不是单元测试,它测到别的东西。这时候你的脑袋里会不会像浆糊一样,还有这样说法,单元测试还能测到别的东西?那么我们来思考一个问题,什么是(真正的)单元测试,为什么
阅读更多

事件集线器

事件集线器我们知道,各种抽象工厂,外观以及其他模式都能在一定程度上解耦依赖和隔离代码。这些方法的使用都是为了更好的编写可测试的代码。今天我们介绍另一种方法,那就是事件的使用。总的来说,所有应用程序都与消息传递有关系,因此很大可能会发生耦合,因为代码必须拿到另一个对象的引用,这样才能给另一个对象发送消息或接收消息。因此这里可能存在两种耦合,一种是全局依赖,另一种是注入对象依赖。从前面的关于耦合的程度
阅读更多

依赖注入

依赖注入前面我们介绍了耦合解耦的方法,比如工厂模式解耦,今天我们重点学习依赖注入解耦。首先我们需要理解的是注入和模拟是松散的关系。如果一个对象的依赖项需要注入,而另外一个对象此时负责构建该对象。我们就把问题皮球提到了另外一层?的确如此,皮球必须止于某个地方,而这个地方是应用程序或者测试开始的地方。依赖注入器可以为代码构建和注入完全成型的对象。依赖注入还有一点需要提醒的是作用域的问题,也就是作用域通
阅读更多

扇出

扇出扇出是测量函数直接或者间接依赖的模块或对象的数量。有一个经验上的代码复杂度计算公式就是:(fan_in * fan_out)的平方一些研究表明:复杂度的值与软件变更有98%的相关性。比如:越复杂的函数或者模块,该函数或者模块就越有可能发生Bug。那么扇出的定义到底是什么呢?过程A的扇出是表示过程A的内部流程数量(指挥别人做的)和过程A所更新的数据结构数量(自己做的)之和。扇出就衡量一个函数做多
阅读更多

js设计模式(存储库-策略-访问者)

存储库(Memento)Memento 表示存储库,其存储对象的状态。在应用程序中可能存在需要保存和恢复对象状态的场景。大多数时候,使用 JSON 的对象的序列化和反序列化属性有助于实现这种设计模式。var Toy = function (name, country, city, year) { this.name = name; this.country = country;
阅读更多

RxJs基础

Rxjs基础我们知道在Rxjs中有几类基础组件,它们分别是:1、Observables2、Observers3、Operators4、Subjects5、Schedulers以上这些组件是Rxjs的核心构建块。我们需要理解它们如何协同工作以便提供强大的功能。一旦对它们有了更高层次的理解,使用起来将会得心应手。那么,让我们一一来看看它们。先来看一个例子:import { from } from "r
阅读更多

JPA——Cascade理解

首先,我们提出两个比较有意思的问题:我们得理解什么是JPA中的Cascade?其次我们需要理解Cascade在什么情况下使用? JPA中的Cascade是什么JPA将实体状态转化为数据库的DML执行语句。一般情况下,我们都是对实体图(也可以称为实体网络图)进行操作,JPA 允许我们将实体状态更改从父实体传播到子实体。这些行为是通过 CascadeType 映射配置的。 JPA中
阅读更多

Rx初步理解

这一节我们来理解Rx的一些基本概念:1、什么是Rx?首先,官网的介绍是:An API for asynchronous programming with observable streams我们对这段话的理解有三个层次:1、An API:它首先是一个编程接口规范,不同的语言有不同的实现,但是API接口应该是一致的。2、For asynchronous programming:在异步编程中使用。比如
阅读更多

js设计模式(解释器)

js设计模式(解释器)上几节我们主要介绍了结构设计模式,今天我们开始学习行为设计模式,主要有以下几种类别Chain of ResponsibilityCommandInterpreterIteratorMediatorMementoObserverStateStrategyTemplateVisitor今天我们先学习解释器模式不是所有解决方案都是相同的。在许多应用程序中,您可能需要添加额外的代码行
阅读更多

js设计模式(代理)

代理设计模式代理模式提供了一个占位符对象,而不是实际的对象。占位符对象将控制对实际对象值的访问。例如,我们的玩具工厂位于世界许多地方。每个地方都生产许多玩具。每个地方都生产许多玩具。使用代理模式,可以更轻松地了解每个位置生产了多少玩具。function GeoCoder() { this.getLatLng = function (address) { if (addres
阅读更多

js设计模式(享元)

享元设计模式当对象需要在对象之间共享时使用此模式。对象将是不可变的。为什么?由于对象是由其他人共享的,因此不得更改它们。享元模式存在于 Javascript 引擎中。例如,Javascript 引擎维护一个字符串列表,这些字符串是不可变的并且可以在应用程序之间共享。我们的玩具厂每个玩具都有一个类型每个玩具都有一个制造国每个玩具都有生产年份。这些属性可以保留在享元模型中。function Flywe
阅读更多

js设计模式(组合,装饰)

组合设计模式正如名称所暗示的,组合模式创建原始对象或对象集合。这有助于构建深度嵌套的结构。在我们的玩具工厂,组合有以下功能:我们有两个部门,一个是手动部门,两个是自动化部门。在手动部门,我们有一堆玩具(叶子节点)。在自动化部门,我们有另一套玩具(叶子节点)。var Node = function (name) { this.children = []; this.name = na
阅读更多

js设计模式(桥接)

桥接模式桥接是著名的高级架构模式。它通过提供不同的抽象级别。结果,组件对象松散耦合。每个成为组件的对象都将拥有自己的接口。在我们生产星球大战玩具的玩具厂,有两种不同的品种。一套玩具可以使用遥控器进行操作。另一组玩具使用电池供电并产生不同的声音。桥接模式有助于构建这种高级架构。var Remote_Control = function (output) { this.output = out
阅读更多

js设计模式(适配器)

上两节我们介绍了创建型设计模式中的五种。今天我们继续学习结构型设计模型,它们分别是:适配器桥接组合装饰门面享元代理适配器当对象的属性或方法需要从一个转换到另一个时,使用适配器设计模式。当具有不匹配接口的组件必须相互协作时,该模式非常有用。适配器模式也称为包装器模式。让我们通过我们的玩具工厂来理解这一点:玩具厂有一个运输部门。我们正计划从旧的运输部门迁移到新的运输部门。但是,对于当前库存,我们需要保
阅读更多

RxJs——map,filter第二种实现

上一节我们实现了map和filter函数,我们将这些函数都挂载在MyObservable对象上,这里存在一个问题,类似map和filter这样的操作型函数很多,所以不可能将他们都挂载在MyObservable对象上,因此,这里出现了第二种实现。 这些操作函数能串联起来的本质就是能够形成嵌套调用,因此我想到了使用pipe,pipe的本质是接收一个 RxJS 操作符的运行结果作为参数,并返回
阅读更多

RxJs——错误处理(一)

错误处理是RxJs中重要组成部分,我们在响应式编程中几乎都要使用到;然而RxJs中的错误处理不像在其他库中的错误处理那么容易理解。小窍门就是关注Observable的约定,这样就容易理解RxJs中错误处理。 今天我们介绍一些常见的错误处理策略,涵盖一些常用场景,当然还是从Observable的基础知识——Observable的约定。Observable约定首先我们需要理解的是给定的流只能
阅读更多

RxJs——错误处理(二)

从前文我们知道,错误处理有两种方式,一种是重新抛出一个错误,另一个是提供一个默认的回调值。今天我们介绍错误处理的另一种方式,先来看看重试。重试策略有一点需要记住,一旦流出现了错误,我们不能恢复它。但是没有什么能阻碍我们订阅其派生类对应的Observable,并且创建一个新的流。这种策略的工作原理是:1、我们将获取输入Observable并且订阅它,这将创建一个新的流。2、如果流没有出错,我们将在输
阅读更多

JPA——CascadeType.PERSIST

今天我们来学习一种简单的级联关系——CascadeType.PERSIST。业务分析首先,我们使用一个具体的业务场景,每个Post内容都有一个PostDetails细节,它们之间是一对一的关系,按照业务原则,我们来看看Post和PostDetails之间的关系是组合还是聚合,没有了Post,那么PostDetails没有存在的必要,因此PostDetails没有单独存在的可能性。因此它们之间是组合
阅读更多

使用jpa和querydsl来实现嵌套属性的查询

1、引入相关的jpa和querydsl相关的包<dependency> <groupId>com.querydsl</groupId> <artifactId>querydsl-jpa</artifactId> <version>${querydsl.version}</version
阅读更多
X

欢迎加群学习交流

联系我们