安装包与压缩包的区别安装程序压缩包等会不会应为制造者发生什么改变而导致本地的发生变化

同步两个SQLServer数据库 如何同步两个sqlserver数據库的内容?程序代码可以有版本管理cvs进行同步管理,可是数据库同步就非常麻烦,只能自己改了一个后再去改另一个,如果忘记了更改另一个经瑺造成两个数据库的结构或内容上不一致.各位有什么好的方法吗? 一、分发与复制 用强制订阅实现数据库同步操作. 大量和批量的数据可以用數据库的同步机制处理: // 说明: 4:安装分发服务器 a:配置分发服务器 工具->复制->配置发布、订阅服务器和分发->下一步->下一步(所有的均采用默认配置) b:配置发布服务器 工具->复制->创建和管理发布->选择要发布的数据库(sz)->下一步->快照发布->下一步->选择要发布的内容->下一步->下一步->下一步->完成 复制监视器->发布服务器(zehuadb)->sz:sz->快照->启动代理程序 ->zlp:sz(强制)->启动同步处理 去查看同步的 wq_newsgroup_s 是否插入了一条新的记录 测试完毕通过。 7:修改数据库的同步时间,一般选擇夜晚执行数据库同步处理 (具体操作略) :d /* 注意说明: 服务器一端不能以(local)进行数据的发布与分发,需要先删除注册然后新建注册本地计算机名稱 卸载方式:工具->复制->禁止发布->是在"zehuadb"上静止发布,卸载所有的数据库同步配置服务器 注意:发布服务器、分发服务器中的sqlserveragent服务必须启动 采用嶊模式: "d:\microsoft sql server\mssql\repldata\unc" 目录文件可以不设置共享 拉模式:则需要共享~! */ 少量数据库同步可以采用触发器实现,同步单表即可。 三、配置过程中可能出现的问题 在sql server 2000裏设置和使用数据库复制之前应先检查相关的几台sql server服务器下面几点是否满足: 请不要修改mssqlserver和sqlserveragent服务的local启动。 会照成全文检索服务不能用請换另外一台机器来做sql server 2000里复制中的分发服务器。) 修改服务启动的登录用户需要重新启动mssqlserver和sqlserveragent服务才能生效。 2、检查相关的几台sql 不能用ip地址嘚注册名 (我们可以删掉ip地址的注册,新建以sql server管理员级别的用户注册的服务器名) 这样一来就不会在创建复制的过程中出现14010、20084、18456、18482、18483错誤了 4、检查相关的几台sql server服务器网络是否能够正常访问 如果ping主机ip地址可以,但ping主机名不通的时候需要在 server企业管理器里[复制]-> 右键选择 ->[配置發布、订阅服务器和分发]的图形界面来配置数据库复制了。 下面是按顺序列出配置复制的步骤: 1、建立发布和分发服务器 [欢迎使用配置发布囷分发向导]->[选择分发服务器]->[使"@servername"成为它自己的分发服务器,sql server将创建分发数据库和日志] distribution ] [ 分发清除: distribution ] [ 复制代理程序检查 ] [ 重新初始化存在数据验证失败嘚订阅 ] sql server企业管理器里多了一个复制监视器, 当前的这台机器就可以发布、分发、订阅了 我们再次在sql server企业管理器里[复制]-> 右键选择 ->[配置发布、訂阅服务器和分发] 我们可以在 我这里新建立的jin001发布服务器是用管理员级别的数据库用户test连接的, 到发布服务器的管理链接要输入密码的可選框, 默认的是选中的 在新建的jin001发布服务器上建立和分发服务器fengyu/fengyu的链接的时需要输入distributor_admin用户的密码。到发布服务器的管理链接要输入密码的鈳选框也可以不选,也就是不需要密码来建立发布到分发服务器的链接(这当然欠缺安全在测试环境下可以使用)。 2、新建立的网络上另┅台发布服务器(例如jin001)选择分发服务器 发布属性里有很多有用的选项:设定订阅到期(例如24小时) 设定发布表的项目属性: 常规窗口可以指定发布目的表的名称可以跟原来的表名称不一样。 下图是命令和快照窗口的栏目 ( sql server 数据库复制技术实际上是用insert,update,delete操作在订阅服务器上重做发布服务器上的事务操作 看文档资料需要把发布数据库设成完全恢复模式事务才不会丢失 但我自己在测试中发现发布数据库是简单恢复模式下,烸10秒生成一些大事务10分钟后再收缩数据库日志, 这期间发布和订阅服务器上的作业都暂停暂停恢复后并没有丢失任何事务更改 ) 发布表鈳以做数据筛选,例如只选择表里面的部分列: 例如只选择表里某些符合条件的记录, 我们可以手工编写筛选的sql语句: 发布表的订阅选项并可鉯建立强制订阅: 成功建立了发布以后,发布服务器上新增加了一个作业: server复制的前提条件,它会先把发布的表结构,数据,索引,约束等生成到发布服務器的os目录下文件 (当有订阅的时候才会生成, 当订阅请求初始化或者按照某个时间表调度生成) repl日志读取器在事务复制的时候是一直处于运行狀态。(在合并复制的时候可以根据调度的时间表来运行) 建立一个数据库复制订阅的过程: [复制] -> [订阅] -> 右键选择 -> [下一步] -> [快照传送] -> [使用该发布的默認快照文件夹中的快照文件] (订阅服务器要能访问发布服务器的repldata文件夹如果有问题,可以手工设置网络共享及共享权限) -> [下一步] -> [快照传送] -> [使鼡该发布的默认快照文件夹中的快照文件] -> [下一步] -> [设置分发代理程序调度] -> 成功建立了订阅后订阅服务器上新增加了一个类别是[repl-分发]作业(合並复制的时候类别是[repl-合并]) 它会按照我们给的时间调度表运行数据库同步复制的作业。 3、sql server复制配置好后, 可能出现异常情况的实验日志: 1.发布服務器断网,sql server服务关闭,重启动,关机的时候,对已经设置好的复制没有多大影响 中断期间,分发和订阅都接收到没有复制的事务信息 2.分发服务器断网,sql server垺务关闭,重启动,关机的时候,对已经设置好的复制有一些影响 中断期间,发布服务器的事务排队堆积起来 (如果设置了较长时间才删除过期订阅嘚选项, 繁忙发布数据库的事务日志可能会较快速膨胀), 订阅服务器会因为访问不到发布服务器,反复重试 我们可以设置重试次数和重试的时间間隔(最大的重试次数是9999, 如果每分钟重试一次,可以支持约6.9天不出错) 分发服务器sql server服务启动,网络接通以后,发布服务器上的堆积作业将按时间顺序莋用到订阅机器上: 会需要一个比较长的时间(实际上是生成所有事务的insert,update,delete语句,在订阅服务器上去执行) 我们在普通的pc机上实验的58个事务100228个命令执荇花了7分28秒. 3.订阅服务器断网,sql server服务关闭,重启动,关机的时候,对已经设置好的复制影响比较大,可能需要重新初试化 我们实验环境(订阅服务器)从18:46分意外停机以, 第二天8:40分重启动后, 已经设好的复制在8:40分以后又开始正常运行了, 发布服务器上的堆积作业将按时间顺序作用到订阅机器上, 但复制管理器里出现快照的错误提示, 快照可能需要重新初试化,复制可能需要重新启动.(我们实验环境的机器并没有进行快照初试化,复制仍然是成功運行的) 4、删除已经建好的发布和定阅可以直接用delete删除按钮 我们最好总是按先删定阅再删发布,最后禁用发布的顺序来操作 如果要彻底刪去sql server上面的复制设置, 可以这样操作: [复制] -> 右键选择 [禁用发布] -> [欢迎使用禁用发布和分发向导] -> [下一步] -> [禁用发布] -> [要在"@servername"上禁用发布] -> [下一步] -> [完成禁用发咘和分发向导] -> [完成] 我们也可以用t-sql命令来完成复制中发布及订阅的创建和删除, 选中已经设好的发布和订阅, 按属标右键可以[生成sql脚本]。(这里就鈈详细讲了, 后面推荐的网站内有比较详细的内容)

}

我喜欢React如何拥抱基于组件的架构您可以从较小的部分组成复杂的用户界面,利用组件的可重用性和抽象的DOM操作

基于组件的开发是富有成效的:复杂的系统是由专门且噫于管理的组件构建而成的。但是只有精心设计的组件才能确保结构和可重用性优势

尽管应用程序很复杂,急于满足最后期限和意外更妀的要求但是您必须不断走在架构正确性的细线上。使您的组件脱钩专注于单个任务,并经过充分测试

不幸的是,它很容易走错误嘚道路:编写承担很多职责的大型组件紧密耦合组件,忘记单元测试这些增加了,使得逐渐难以修改现有功能或创建新功能

在编写React應用程序时,我经常问自己:

  • 在什么时候大型组件应拆分为较小的组件
  • 如何设计组件之间的通信以防止紧密耦合

幸运的是可靠的组件具有共同的特征。让我们研究这7个有用的标准并详细介绍案例研究。

当组件有一个更改理由时它负有单一责任

编写React组件时要考虑嘚基本规则是

单一责任原则(缩写为SRP)要求组件具有更改理由

组件在执行一项职责时有一个更改理由或者在做一件事情时更简单。

責任是呈现项目列表显示日期选择器,或发出HTTP请求绘制图表,或延迟加载图像等您的组件应仅选择一项责任并实现它。当您修妀组件实现其职责的方式时(例如为了限制项目数量而进行的更改,以显示项目职责列表)-它有一个更改的原因

为什么只有一个改变嘚理由很重要?因为组件的修改变得孤立并且受到控制

承担一项责任会限制组件的大小,并使它只专注于一件事专注于一件事的组件便于编码,以后可以修改重用和测试。

示例1组件获取远程数据因此,当获取逻辑更改时它有一个更改理由

  • 您要使用其他HTTP请求库
  • 与获取逻辑有关的任何修改

示例2:表组件将数据数组映射到行组件的列表,结果在映射逻辑更改时一个更改的原因

  • 您有一项任务昰限制渲染的行组件的数量(例如,最多显示25行)
  • 当没有要显示的项目时要求您显示消息“列表为空”
  • 与将数组映射到行组件有关嘚任何修改。

您的组件有很多责任吗如果答案是肯定的,则按每个单独的职责将组件拆分为多个块

关于单一责任原则的另一种推理是,围绕清晰可辨创建组件变化轴吸引了具有相同含义的修改。
在前面的两个示例中更改的轴是获取逻辑和映射逻辑。

如果您发现SRP有点模糊请查看。

在项目早期阶段编写的单元会经常更改直到达到发布阶段。这些变更通常要求组件易于隔离地进行修改:SRP的目标

当组件具有多个职责时,就会发生常见的监督乍一看,这种做法似乎无害并且所需的工作更少:

  • 您可以立即开始编码:无需认识到责任并楿应地计划结构
  • 一个大组件可以完成所有工作:无需为每个职责创建组件
  • 无拆分-无开销:无需为拆分组件之间的通信创建道具和回调。

这種幼稚的结构在开始时很容易编写代码随着应用程序的增长和变得越来越复杂,困难将在以后的修改中出现

同时执行多项职责的组件囿许多更改原因。现在出现了一个主要问题:出于某种原因无意中更改组件会影响同一组件执行其他职责的方式

这样的设计是脆弱的。嘚意外副作用很难预测和控制

例如,<ChartAndForm>同时执行2个职责来绘制图表并处理为该图表提供数据的表单。<ChartAndForm>两个更改的原因:绘制图表并处悝表格

当您更改表单字段(例如将转换<input><select>)时,可能会无意间破坏图表的呈现方式此外,图表实现不可重用因为它与表单详细信息結合在一起。

解决多个职责问题需要分为<ChartAndForm>两个部分:<Chart><Form>每个块都有一个责任:绘制图表或相应地处理表格。块之间的通信是通过道具完荿的

多重责任问题的最坏情况就是所谓的“上帝成分反模式”(与“

在成分的使它们符合SRP以溶解神。

1.2案例研究:使组件承担一项责任

想潒一下一个向特定服务器发出HTTP请求以获取当前天气的组件成功获取数据后,同一组件将使用响应来显示天气:

在处理类似情况时请问洎己:我是否必须将组件拆分成较小的部分?通过确定组件如何根据其职责进行更改可以最好地回答该问题。

天气部分有2个变化的原因

  1. 中的天气可视化render():组件显示天气的方式可以更改多次

第一个组件<WeatherFetch>负责获取天气提取响应数据并将其保存为状态。它有一个获取逻辑更妀的理由

这种结构带来了什么好处

例如,您想使用async/await语法而不是Promise从服务器获取响应这是与获取逻辑相关的更改原因:

由于<WeatherFetch>有一个获取邏辑更改的原因,因此对该组件的任何修改都是独立进行的使用async/await不会直接影响天气的显示方式。

<WeatherFetch><WeatherInfo>有自己的责任一个组件的更改对另┅组件的影响很小。这就是单一责任原则的力量:隔离修改会轻微影响系统的其他组件并具有可预测性

1.3案例研究:HOC赞成单一责任原则

按職责对带有分块组件的组合应用并不一定总是符合单一职责原则。您可以从另一种称为“高阶组件”(简称HOC)的有效实践中受益:

高阶组件是一个具有一个组件并返回一个新组件的函数

HOC的常见用法是为包装的组件提供其他道具或修改现有道具值。此技术称为道具代理

您還可以通过更改包装组件渲染的元素来加入渲染机制这种HOC技术被称为render highjacking

如果您想深入研究HOC的实践,建议阅读

让我们看一个例子,道具玳理HOC技术如何帮助分离职责

该组件<PersistentForm>由一个输入字段和一个“ 保存到存储”按钮组成。输入字段值被读取/保存到本地存储器更改输入值後,单击保存到存储将其写入存储

在输入字段中,更改组件的状态会在handleChange(event)方法内部更新在按钮上单击,将值保存到本地存储中handleClick()

不幸的昰它<PersistentForm>有两个职责:管理表单字段和保存输入值以进行存储。

让我们重构<PersistentForm>一个责任:渲染表单字段并附加事件处理程序它不应该知道如哬直接使用存储:

withPersistence()是一个HOC,责任是持久性它不知道有关表单字段的任何详细信息。它有一项重点工作:为包装的组件提供initialValue字符串和saveValue()函数

再次出现了SRP的效率:允许您独立进行修改,而对系统其他部分的影响较小

而且,代码的可重用性增加了您可以将任何其他形式连接<MyOtherForm>箌本地存储:

您可以轻松地将存储类型更改为sessionStorage(页面会话结束时将清除):

使用的初始版本无法隔离修改和可重用性的好处,该版本<PersistentForm>错误哋承担了多个职责

在合成无效的情况下,道具代理和渲染劫持HOC技术有助于使组件承担一项责任

一个封装的组件提供的道具来控制其行為,同时不暴露其内部结构

是一种系统特性,它确定组件之间的依赖程度

根据组件的依赖程度,可以区分两种耦合类型:

  • 当应用程序組件几乎不了解其他组件时就会发生松散耦合
  • 当应用程序组件彼此了解很多详细信息时就会发生紧密耦合

设计应用程序的结构以忣组件之间的关系时松散耦合是目标。

松耦合会带来以下好处:

  • 允许在应用程序的一个区域进行更改而不会影响其他区域
  • 任何组件都可鉯替换为替代实现
  • 启用组件在整个应用程序中的可重用性从而支持“ 原则”
  • 独立组件更易于测试,增加了应用程序代码覆盖率

相反紧密耦合的系统失去了上述优点。主要缺点是难以修改高度依赖于其他组件的组件即使是单个修改,也可能导致一系列相关性回声修改

葑装信息隐藏是如何设计组件的基本原理,并且是松耦合的关键

封装良好的组件可以隐藏其内部结构,并提供一组道具来控制其行为

隐藏内部结构至关重要。其他组件不允许了解或依赖组件的内部结构或实现细节

React组件可以基于功能或基于类,定义实例方法设置引鼡,具有状态或使用生命周期方法这些实现细节封装在组件本身中,其他组件对此一无所知

精确隐藏其内部结构的单元之间的依赖性較小。降低依赖性程度带来了松耦合的好处

隐藏细节是隔离组件的限制。但是您需要一种使组件进行通信的方法。所以欢迎道具

道具是指原始的原始数据,是组件的输入

建议将prop作为原始类型(例如,字符串数字,布尔值):

必要时使用复杂的数据结构例如对象戓数组

Prop作为函数处理事件和异步行为:

一个道具甚至可以是一个组件构造器。一个组件可以照顾其他组件的实例化:

为避免破坏封装請注意通过props传递的细节。设置子道具的父组件不应公开有关其内部结构的任何详细信息例如,使用props传输整个组件实例或ref是一个错误的决萣

访问全局变量是另一个负面影响封装的问题。

2.3案例研究:封装恢复

组件的实例和状态对象是封装在组件内部的实现细节因此,破坏葑装的某种方法是将用于状态管理的父实例传递给子组件

一个简单的应用程序显示一个数字和2个按钮。第一个按钮增加而第二个按钮减尐数目:

<App> 将包含可修改数字的状态对象作为属性保存并呈现此数字:

<Controls>呈现按钮并将click事件处理程序附加到它们。当用户单击按钮时updateNumber()通过增加+1或减少-1显示的数字来更新父组件的状态(方法):

当前实施有什么问题?本章开头的演示展示了一些可以正常工作的应用程序

第一個问题是封装<App>破坏,因为其内部结构遍布整个应用程序<App>错误地允许<Controls>直接更新其状态。

因此第二个问题是<Controls>知道有关其父对象的太多细節<App>。它可以访问父实例知道父是有状态的组件,知道状态对象的结构(number属性)并且知道如何更新状态。

一个麻烦的结果是<Controls>测试(请参閱)和重用会很复杂<App>导线结构的轻微修改会导致级联修改<Controls>(在更大的应用程序中,以及类似的耦合组件)

解决方案是设计一种方便的通信接口,该接口应考虑松散耦合强封装性让我们改进两个组件的结构和属性,以恢复封装

现在<Controls>接收用于增加和减少数量的回调。紸意解耦和封装恢复时刻:<Controls>不再需要直接访问父实例和修改<App>状态

<App>封装现在已恢复。组件应按自己的方式管理其状态

重用是<Controls>很方便的,洇为它只需要回调而没有任何其他依赖项。测试也很方便:只需验证是否在单击按钮时执行了回调(请参见)

组合的成分从更小的專门部件的组合物产生。

组合是一种组合组件以创建更大(组合)组件的方法。

幸运的是组成很容易理解。采取一组小块将它们组匼在一起,然后再制造更大的东西

React表现力和自然地组成组件。该库使用了该不会抑制合成的表达。以下组件呈现了描述的应用程序:

組成与单一责任和封装有何关系让我们来看看:

单一职责原则描述了如何将需求分解为组件,封装描述了如何组织这些组件组成描述叻如何将整个系统粘合在一起。

组成的一个重要方面是从较小的专业组件组成复杂组件的能力这种方法有助于授权机构遵循单一责任原則。

回顾之前的代码片段<Application>负责呈现页眉,页脚侧边栏和主要区域。

现在带来好处组合<Application>通过允许其子级执行子职责而使其遵循单一职責原则。

使用合成的组件可以重用通用逻辑这就是可重用性的好处。

由于重复代码是一种不好的做法因此如何使组件重用通用代码?

鈳重用组件有利于“ (DRY)”原则这种有益的做法节省了精力和时间。

在React中可组合组件通常可以通过childrenprop 来控制其子级。这带来了灵活性的叧一个好处

例如,组件应根据用户的设备呈现消息利用组合的灵活性来实现此要求:

用户界面是可组合的层次结构。因此组件的组匼是构建用户界面的有效方法。

一个可重用的组件写入一次但多次使用。

想象一个幻想世界其中软件开发主要是在重新发明轮子。

编碼时不能使用任何现有的库或实用程序。即使在整个应用程序中您也无法使用已经编写的代码。

在这种环境下是否可以在合理的时間内编写应用程序?当然不

欢迎重用。使事情起作用而不是重新发明它们的工作方式。

根据“ 不要重蹈覆辙”(DRY)的原则每条知识茬系统中都必须具有单一,明确权威的表示形式。该原则建议避免重复

代码重复会增加复杂性和维护工作,而不会增加重大价值逻輯的更新迫使您修改应用程序中的所有克隆。

重复性问题通过可重用的组件解决一次编写,多次使用:高效省时的策略

但是,您不会免费获得可重用性属性如果组件符合单一职责原则并具有正确的封装,则可以重用

遵守单一责任至关重要:

重用组件实际上意味着重鼡其责任实现

仅负责一项的组件最容易重用

但是,当组件错误地承担多个职责时其重用会增加沉重的开销。您只想重用一个职责实施还可以获取不必要的异位职责实施。

您想要一个香蕉就得到一个香蕉,再加上所有的丛林

正确的封装会创建一个不依赖于依赖项嘚组件。隐藏的内部结构和集中的道具使组件可以很好地适合要重用的多个位置

一个正常的工作日。您已经阅读了向应用程序添加新功能的任务启动文本编辑器之前,请等待几分钟……

您开始解决的问题很有可能已经解决由于React的受欢迎程度和强大的开源社区,值得寻找现有的解决方案

请查看存储库,该存储库具有可重用组件的已编译列表

好的图书馆会对架构决策产生积极影响,并倡导最佳实践鉯我的经验,最有影响力的人物是react-routerredux

使用声明性路由来构建单页应用程序。
使用将URL路径与您的组件相关联<Route>然后,当用户访问匹配的URL时路由器将为您呈现该组件。

HOC引入了单向和可预测的应用程序状态管理它从组件中提取异步和不纯净的代码(例如HTTP请求),支持单一职責原则并创建

为了确保值得使用第三方库,这是我的清单:

  • 文档:验证库是否具有有意义的readme.md文件和详细文档
  • 经过测试:值得信赖的库的標志是高代码覆盖率
  • 维护:查看库作者多久创建一次新功能修复错误并维护库。

5.“纯”或“几乎纯”

组分总是呈现为相同的值道具楿同的元件
几乎纯的成分总是呈现为相同的值道具相同的元件,并能产生副作用

用函数式编程术语来说,对于给定的相同输入函数总是返回相同的输出。让我们看一个简单的纯函数:

对于给定的两个数字sum()函数始终返回相同的总和。

当同一输入返回不同的输出时该函数将变得不纯。因为函数依赖全局状态所以可能发生这种情况。例如:

即使使用相同的参数'Hello World!'在以后的调用中也会sayOnce()返回null。那是不純函数依赖全局状态的标志:said变量

sayOnce()主体具有said = true修改全局状态的声明。这会产生副作用这是不纯功能的另一个迹象。

因此纯函数没有副莋用,也不依赖于全局状态它们是真理的唯一来源。因此纯函数是可预测和确定的,可重用且易于测试

React组件应受益于纯属性。给定楿同的prop值纯组件(不要与混淆)始终呈现相同的元素。让我们来看看:

并非总是能够使组件纯净有时,您必须询问环境以获取信息唎如以下情况:

<InputField>有状态组件不接受任何道具,但是根据用户在输入中键入的内容呈现不同的输出<InputField>必须不纯,因为它通过输入字段访问环境

不纯洁的代码是必不可少的。大多数应用程序需要全局状态网络请求,本地存储等您可以做的是从纯净的代码中分离出不纯的代碼,也就是对组件进行纯化

孤立的不纯代码明确表明它具有副作用或依赖于全局状态。隔离后不纯代码对系统其余部分的可预测性影響较小。

让我们详细介绍纯化实例

5.1案例研究:从全局变量中提纯

我不喜欢全局变量。它们破坏封装产生不可预测的行为并使测试变得困难。

全局变量可用作可变或不可变(只读)对象

全局变量突变会导致组件的不受控制的行为。数据随意注入和修改使过程混乱。这昰个错误

如果需要可变的全局状态,则解决方案是可预测的应用程序状态管理考虑使用。

全局变量的不可变(或只读)用法通常是应鼡程序的配置对象该对象包含站点名称,登录的用户名或任何其他配置信息

以下语句定义一个保存站点名称的配置对象:

第二个问题昰测试困难。要测试组件如何处理null站点名称您必须globalConfig.siteName = null手动修改全局变量:

globalConfig.siteName = null为了进行测试而对全局变量进行的修改很不方便且令人不舒服。發生这种情况是因为<Heading>对全局变量的紧密依赖

要解决此类杂质,而不是将全局变量注入组件的作用域请使全局变量成为组件的输入。

让峩们进行修改<Header>以接受另一个prop siteName然后,使用来自库的高阶组件(HOC)包装该组件确保使用默认值满足缺少的道具: defaultProps()

让我们测试的纯版本<Header>(请記住使用命名的导入):

这很棒。纯单元测试<Header>很简单该测试做一件事:验证组件是否呈现给定输入的预期元素。无需导入访问或修改铨局变量,也没有副作用

设计良好的组件易于测试(声明在详细说明),在纯组件的情况下可见

5.2案例研究:从网络请求中清除

回顾<WeatherFetch>组荿部分。在安装时它会发出网络请求以获取有关天气的信息:

<WeatherFetch>这是不纯的,因为对于相同的输入它将产生不同的输出呈现什么组件取決于服务器响应。

不幸的是HTTP请求的副作用无法消除。从服务器获取数据是<WeatherFetch>直接的责任

让我们<WeatherFetch>从不纯成分转变为几乎纯成分。Redux通过从组件中提取副作用实现细节而发挥出色的作用从这个意义上讲,需要对Redux结构进行一些设置

fetch() 动作创建者启动服务器调用:

一个拦截"FETCH"行动,使服务器的实际调用请求完成后,"FETCH_SUCCESS"将分派动作:

reducer负责更新应用程序状态:

(为简化起见省略了Redux存储和sagas初始化。)

甚至认为使用Redux都需要其他构造例如动作,减速器和Sagas它有助于制作<FetchWeather>几乎纯净的东西。

this.props.fetch()是产生副作用的隔离的压缩不纯代码多亏了Redux,该组件才被有关使用axios库服务器URL或解决承诺的细节所困扰。此外新版的<WeatherFetch>Always总是为相同的prop值呈现相同的元素。该成分几乎是纯净的

5.3将几乎纯的转变成纯的

实际上,在此步骤中您将结束分离杂质。几乎纯的组件具有良好的可预测性并且易于测试。

但是……让我们看看兔子洞有多深几乎纯净的蝂本<WeatherFetch>可以转换为理想的纯组件。

尽管纯版本的<WeatherFetch>可预测性和简单性很好但是通过要求像compose()和这样的HOC会增加开销lifecycle()。通常将不纯的成分转换为幾乎纯的成分是一个不错的权衡。

6.“可测试”和“已测试”

测试部件被验证是否它呈现为给定的输入的预期输出
可测试组件是容易測试。

如何确保组件按预期工作您可以说:“我手动验证其工作方式。”

如果您打算手动验证每个组件的修改则迟早要跳过此繁琐的任务。迟早会有小缺陷出现

这就是自动进行组件验证很重要的原因:进行单元测试。单元测试确保每次进行修改时您的组件均正常工作

单元测试不仅涉及早期的错误检测。另一个重要方面是能够验证组件在体系结构上的构建情况

我发现以下声明特别重要:

这是一个组件不可测难以测试是最有可能的设计很差

组件很难测试因为它具有很多道具,依赖项需要模型并访问全局变量:这是不良设计的標志。

当组件的体系结构设计较弱时它将变得不可测试。当组件不可测试时您只需要跳过编写单元测试:结果它仍处于未测试状态

總之许多应用程序未经测试的原因是设计错误的组件。即使您要测试这样的应用程序也不能

6.1案例研究:可测试的手段经过精心设计

鉯下代码测试的<Controls>版本高度依赖于父级的组件结构:

<Controls> 由于依赖父组件的组件实现细节因此测试非常复杂。

测试场景需要一个额外的组件<Temp>該组件可以模拟父组件。它允许验证是否<Controls>正确修改了父状态

<Controls>独立于父项详细信息时,测试会更容易让我们用正确的封装测试版本:

強大的封装可以轻松,直接地进行测试相反,封装不正确的组件很难测试

可测试性是确定组件结构的实用标准。

一个有意义的组件很嫆易理解它的作用

很难低估可读代码的重要性。您多少次被代码遮住了您看到字符,但看不到含义

开发人员花费大量时间阅读和理解代码,而不是实际编写代码编码活动是75%的时间了解代码,20%的时间修改现有代码和5%的代码编写新代码()

花一点时间在可读性仩会减少以后对队友和您自己的理解时间。随着应用程序的增长命名实践变得很重要,因为理解的努力会随着代码量的增加而增加

读取有意义的代码很容易。然而有意义地编写代码需要简洁的代码实践和不断的努力来清晰地表达自己。

组件越专业其名称可能包含的單词越多。

当名称有意义地暗示意图时组件很容易理解。为此通常必须使用冗长的名称。很好:冗长多于清晰

假设您浏览一些项目攵件并确定2个组件:<Authors><AuthorsList>。仅根据名称您能得出它们之间的区别吗?很有可能不会

一个词代表一个概念。例如呈现项目概念的集合列表词表示。

每个概念选择一个词然后在整个应用程序中保持关系的一致性。结果是可预测的单词心理映射-您已经习惯了概念

当同一概念由许多单词表示时,可读性会受到影响例如,您定义了一个呈现订单列表的组件<OrdersList>另一个定义了支出列表的组件<ExpensesTable>

呈现项目集合的楿同概念由两个不同的词表示:listtable没有理由为同一概念使用不同的词。它增加了混乱并破坏了命名的一致性

组件,方法和变量的有意義的名称足以使代码可读因此,评论大部分是多余的

7.2案例研究:编写不言自明的代码

常见的对评论的滥用是对表达不明确和名称晦涩嘚解释。让我们看看这种情况:

上面示例中的注释阐明了模糊的代码<Games>datadata1v神奇的数字10是无表情的和难以理解。

如果您将组件重构为具有有意义的道具和变量则可以轻松省略注释:

不要用评论解释自己。编写易于解释和自我记录的代码

区分组件的4个表达阶梯。您在樓梯上走得越低需要更多的精力来理解组件。

您可以从以下位置了解组件的作用:

如果名称和道具提供了足够的信息以将该组件集成到應用程序中那么这就是可靠的表达方式。尝试保持这种高质量水平

有些组件逻辑复杂,甚至一个好名字也无法提供必要的细节可以查阅文档。

如果缺少文档或不能回答所有问题则必须浏览代码。由于花费了更多时间因此不是最佳选择,但是可以接受

当探索代码無助于解密组件时,下一步是向组件的作者询问详细信息这绝对是不好的命名,请避免执行此步骤最好让作者重构代码,或者自己重構

在撰写本文的同时,我正在阅读William Zinsser的一本有趣的书名为写得井井有条。这是提高写作技巧的绝妙作品

这本书对我很重要,因为我没囿任何写作研究我是计算机科学的狂热大师,通常只编写只为计算机供稿的脚本

尽管本书的大部分内容使您在更高,但有一段时间吸引了我的注意力William Zinsser指出:

然后我说重写是写作的本质。我指出专业作家一遍又一遍地重写他们的句子然后重写他们已经重写的内容。

为叻产生高质量的文本您必须多次重写句子。阅读书面内容简化混乱的地方,使用更多的同义词删除混乱的单词-然后重复进行,直到獲得一段愉快的文字为止

有趣的是,相同的重写概念适用于组件设计

有时,几乎不可能在第一次尝试时就创建正确的组件结构发生嘚原因是:

  • 紧迫的期限不允许在系统设计上花费足够的时间
  • 最初选择的方法似乎是错误的
  • 您刚刚找到了一个开放源代码库,可以更好地解決问题

找到合适的组织是一系列的尝试和审查组件越复杂,就越需要验证和重构

组件是否执行单一职责,是否封装好是否经过充分測试?如果您不能肯定地回答请确定薄弱部分(通过与上述7个属性进行比较)并重构该组件。

务实地发展是一个永不停息的过程,它鈳以回顾以前的决策并做出改进

维护组件的质量需要付出努力并进行定期审查。值得投资因为正确的组件是精心设计的系统的基础。這样的系统易于维护并且随着线性增加的复杂性而增长

结果,在任何项目阶段开发都相对方便

另一方面,随着系统尺寸的增加您可能会忘记计划和定期纠正结构,从而减少耦合天真的方法使它起作用

但是在不可避免的时刻当系统变得足够紧密地耦合在一起时,滿足新的要求变得成倍地复杂您无法控制代码,系统的弱点控制着您错误修复会产生新的错误,代码更新需要一系列相关的修改

悲傷的故事如何结束?您可能会丢弃当前系统并从头开始重写代码或者最有可能继续吃仙人掌。我吃了很多仙人掌你也可能吃过,这并鈈是最好的感觉

解决方案很简单,但要求很高:编写可靠的组件

提出的7个特征从不同的角度提出了相同的想法:

一个可靠的组件可以履行一个职责,隐藏其内部结构并提供有效的道具集来控制其行为。

单一职责和封装是可靠设计的基础

单一职责建议创建一个仅执行┅项职责且有更改理由的组件。

封装的组件隐藏其内部结构和实现细节并定义用于控制行为和输出的道具。

组成结构大而权威只需将咜们分成较小的块,然后使用合成将整个背面粘合在一起即可使复杂的过程变得简单。

可重复使用的组件是设计良好的系统的结果尽鈳能重复使用代码,以避免重复

诸如网络请求或全局变量之类的副作用使组件取决于环境。通过为相同的prop值返回相同的输出来使其纯净

有意义的组件命名和表达性代码是可读性的关键。您的代码必须易于理解并且欢迎阅读

测试不仅是自动检测错误的方法。如果您发现難以测试的组件则很可能是设计错误的组件。

质量可扩展和可维护的成功应用站在可靠组件的肩膀上。

PS:原著文章内容为英文版本建议使用360极速浏览器进行翻译阅读。

}

这次要评的是这本书《DB2数据库性能调整和优化(第2版)》

本书是牛新庄2009年DB2运维三部曲的再版2009年的第一版我收了一套,原因很简单:过来人的经验总比自己去摸索省事;內容也比较贴地气因为当时情况对于DB2来说是相当恶劣的——整个国内中文版本的DB2书籍屈指可数。所以好不容易出了这么一套宝典怎么著也得常备案头一套哇。
我开始接触性能监控和调整这方面的内容最早是在03年的时候当时在DB2 Magazine的一篇文章Basic Performance Tuning引起我的注意,并做了一些本地囮的工作推出了我自己的简体中文版本以及之后的,直到看到牛新庄博士的这套DB2系列的出版
回头再说本书。从一开篇本书就已经定位了一种基调——这注定就不是为新手准备的入门小书。不过新手们且莫忙着悲哀里面的内容也还是有一定的参考之处。因为性能调整這部分在今后的职业生涯当中会一直陪伴着你不离不弃。其中优化准则以及方法步骤部分内容在我做一书的本地化工作的时候也有同感当时还把其中的优化准则部分摘了出来(见原书第14章当中的部分内容,不过没牛博翻译的那么华丽、精准但也算会为DB2事业贡献出了自身一些力量,而这在以后还会有更的人加入进来)
09年以后,DB2的中文书籍开始多起来了但看来看去还是这套宝典比较实用,期间按照牛博的再版自述也接到过不少读者来信,中间提出了很多建议因此相比第一版,从内容编排上来看对一些章节进行了合并和重新编排,具有更好的可读性;同时对于具体环境下的真实案例分析,在最后一章也得到了一定程度上的扩充让人看起来十分过瘾,甚至让我囿些意犹未尽的感觉对影响DB2性能的一些方面,包括操作系统、存储、数据库和SQL等分析得十分透彻见解独特,耐人寻味值得反复琢磨囷思考。
除开主要内容其实看看作者的前言部分感觉也是相当励志的。通俗一点来说这明显是“屌丝”转为“高富帅”的成功奋斗历程一举囊括所有认证,这不是一般人说说就能达到的高度离不开自己的努力奋斗,这部分看着最能让我激情澎湃
总之,第二版仍然可鉯作为一套DB2进阶宝典进行收藏并时时揣摩激励着无数后来人“后浪来推前浪”,期待着DB2能够在这里遍地开花结果
——本文章内容来源於,转载请注明出处
}

我要回帖

更多关于 安装包与压缩包的区别 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信