进攻式编程 与 防御式编程

1、防御式编程
业务的流转应该在参数的正确性下进行。简言之,就是先进行安全性或者存在性检查,然后再执行业务流程。
防御式编程方式例如:DATABASE需要对目标表进行两次扫描,一次是存在性检查,一次为执行业务(如果参数正确的话)。
防御式编程的思想为:在没有真正的操作数据之前,要保证所有的操作或者参数都是正确的,DATABASE只做正确的事。程序编写者应该尽量的预料出可以预料到的错误。我们不应该认为,在表中添加了check约束,就不用在程序中判断某个人的性别只能是男和女。

2、进攻式编程
一般情况下,调用环境已经把要传入程序的参数进行了验证以保证参数是正确的或者大部分是正确的,而此时再采用防御式编程无疑浪费了资源和时间。貌似这个时候采用进攻是编程是正确英明的选择。
先不管参数正确与否,先进行业务操作,在出现错误的时候再进行处理。

 

防御式多用在需要给其他人使用的接口上,
进攻式多用在自己可以掌控的程序开发中。

 

契约式编程

契约式编程是编程的一种方法。那么什么是契约式编程呢?我想这个概念是从“合同”演变过来的。

在人类的社会活动中,契约一般是用于两方,一方(供应者)为另一方(客户)完成一些任务。每一方都期待从契约中获得利益,同时也要接受一些义务。通常,一方视为义务的对另一方来说是权利。契约文档要清楚地写明双方的权利与义务。

契约合同能保障双方的利益,对客户来说,合同规定了供应者要做的工作;对供应者来说,合同说明了如果约定的条件不满足,供应者没有义务一定要完成规定的任务。

同样的道理也适合于软件。设想一个软件单元E。它要达到它的目的(履行契约), E使用的策略可能会包括一系列的子任务,t1, ... tn。如果子任务ti 不是那么简单的,它得调用另一个功能例程(routine)R。换句话说,E把子任务转包给R。这样的情形应该被一个很好定义的“登记表”(roster)来管理双方的义务与权利--契约。

简单的说,就是你不给我想要的东西,我就不干活。

Continue reading "契约式编程"

防御式编程

什么是防御式编程 ?

顾名思义,防御性编程是一种细致、谨慎的编程方法。为了开发可靠的软件,我们要设计系统中的每个组件,以使其尽可能地“保护”自己。我们通过明确地在代码中对设想进行检查,击碎了未记录下来的设想。这是一种努力,防止(或至少是观察)我们的代码以将会展现错误行为的方式被调用。

在软件开发过程中,不可避免的会遇到错误处理,而且这部分对于整个软件的健壮性有非常大的作用,它是软件除了功能性以外最重要的指标了,一个软件成功与否与其健壮性有很大的联系。我在以前的开发中也时常思考错误处理,因为这部分代码逻辑比较不容易梳理清楚。以异常的处理为例,以前通常就采用比较简单粗暴的处理方式:用try..catch加Exception把所有异常都包起来,这样简单省事,写的代码最少,相信很多童鞋曾经跟我一样写过这样的代码,很明显,这样写有很大的问题,最主要的问题在于:

  • Exception会吃掉所有可以处理的异常,使得对于某些我们关心的异常无法捕获,因为对于不同的异常我们可能需要做不同的处理,有些可以在本函数内处理掉,有些需要提示用户(例如文件不存在,网络无法访问),有些需要告诉上一层代码该如何处理,所有这些在直接用Exception处理异常时都无法做到,简而言之就是无法做到异常的精细化处理

那么怎么做才好呢?这部分代码真不少,虽然无关软件功能性,但是确是健壮性的基础。具体如何处理这些没有完全标准的答案,软件设计本来就是一项带有艺术色彩的智力劳动,没有一劳永逸的解决方案,最关键的在于掌握好基础知识,因地制宜地采取措施。下面主要谈谈实现健壮性的基本技术,基本的实现软件健壮性的技术有以下几种:

  • 断言
  • 错误处理
  • 异常
  • 从设计上简化异常处理的技术;隔离程序
  • 辅助调试的代码(print打印之类的小段函数)

Continue reading "防御式编程"

软件开发中的注意事项(常见问题整理)

一、函数定义原则

1、一个函数/方法只做一件事情,不能将多个事情放在一个函数中处理(单一职责原则 SRP)

函数/方法的最小粒度是功能,函数在设计/定义的时候,不能将多个功能柔进一个函数里面,这样函数会变得得膨胀,增加了函数的耦合性,不便于函数管理维护。

例如,有这么一个业务逻辑:用户每天来网站阅读文章,当阅读完毕不同的10篇文章之后,就给他增加10个用户积分。

这个业务逻辑可以拆分为4个功能,也就需要定义为4个函数/方法来实现。

Continue reading "软件开发中的注意事项(常见问题整理)"

在PHPStorm中使用Lge_CodeSniffer(Linux+Windows)

在PHPStorm中使用Lge_CodeSniffer其实相当于在PHPStorm中启用PHP_CodeSniffer检测,并设置检测标准为Lge即可。

在开始本篇文章之前,请先在本地安装好 PHP_CodeSniffer + Lge_CodeSniffer,请参考:

1、Windows:Lge_CodeSniffer/PHP_CodeSniffer的安装配置使用(Windows)

2、Linux:Lge_CodeSniffer/PHP_CodeSniffer的安装配置使用(Linux)

Continue reading "在PHPStorm中使用Lge_CodeSniffer(Linux+Windows)"

Lge_CodeSniffer/PHP_CodeSniffer的安装配置使用(Linux)

Lge_CodeSniffer是基于PHP_CodeSniffer的自定义编码规范检测脚本,编码规范基于PSR-2,对于少部分编写风格做了自定义调整,PSR-2 规范请参考:http://www.php-fig.org/psr/psr-2/,自定义Lge编码规范请参考PDF编码规范文件

本文是在Linux下配置PHP_CodeSniffer+Lge_CodeSniffer代码检测工具的介绍,如果是Windows下的配置,请参考我的另外一篇文章:Lge_CodeSniffer/PHP_CodeSniffer的安装配置使用(Windows)Continue reading "Lge_CodeSniffer/PHP_CodeSniffer的安装配置使用(Linux)"

Gitlab的server端hook简要使用说明

Gitlab的server端hook配置大体步骤是这样的:

1、在gitlab的server端要配置server端hook的项目目录下新建一个 custom_hooks 目录;

2、在custom_hooks目录下新建post-receive钩子文件,chmod该文件的权限为777;

3、在post-receive钩子文件中添加相应的逻辑;

补充说明:gitlab或者github的一个特性是, projectX.git如果是项目的repo地址,那么,与之对应的wiki项目也有一个git的repo地址, 遵循一个命名convention, 即如果项目的地址是projectX.git,那么wiki的项目地址就是projectX.wiki.git, 我们的server端hook的执行逻辑根据这一convention而来;

Continue reading "Gitlab的server端hook简要使用说明"

Git Hooks

和其它版本控制系统一样,Git 能在特定的重要动作发生时触发自定义脚本。 有两组这样的钩子:客户端的和服务器端的。 客户端钩子由诸如提交和合并这样的操作所调用,而服务器端钩子作用于诸如接收被推送的提交这样的联网操作。 你可以随心所欲地运用这些钩子。

安装一个钩子

钩子都被存储在 Git 目录下的 hooks 子目录中。 也即绝大部分项目中的 .git/hooks 。 当你用 git init 初始化一个新版本库时,Git 默认会在这个目录中放置一些示例脚本。这些脚本除了本身可以被调用外,它们还透露了被触发时所传入的参数。 所有的示例都是 shell 脚本,其中一些还混杂了 Perl 代码,不过,任何正确命名的可执行脚本都可以正常使用 —— 你可以用 Ruby 或 Python,或其它语言编写它们。 这些示例的名字都是以 .sample 结尾,如果你想启用它们,得先移除这个后缀。

把一个正确命名且可执行的文件放入 Git 目录下的 hooks 子目录中,即可激活该钩子脚本。 这样一来,它就能被 Git 调用。 接下来,我们会讲解常用的钩子脚本类型。

Continue reading "Git Hooks"

Git rebase

git rebase是对commit history的改写。当你要改写的commit history还没有被提交到远程repo的时候,也就是说,还没有与他人共享之前,commit history是你私人所有的,那么想怎么改写都可以。

而一旦被提交到远程后,这时如果再改写history,那么势必和他人的history长的就不一样了。 git push的时候,git会比较commit history,如果不一致,commit动作会被拒绝,唯一的办法就是带上 -f参数,强制要求commit,这时git会以committer的history覆写远程repo,从而完成代码的提交。虽然代码提交上去了,但是这样可能会造成别人工作成果的丢失,所以使用 -f参数要慎重。

楼主遇到的问题,就是改写了公有的commit history造成的。要解决这个问题,就要从提交流程上做规范。

Continue reading "Git rebase"