php设计模式介绍之编程惯用法第1/3页_PHP教程
在这里总结的许多编程惯用法都是很值得做为单独一个章节的,甚至一本书的。你应该把这章做为PHP模式设计使用惯用法的相关介绍,而且查看一些列出的参考书来进行更深入的学习。
测试你的代码
可能没有什么代码惯用法比测试代码更加重要了。好的测试可以提高开发速度。
可能一开始,这句格言会和你的直觉相矛盾。你可能会断言,测试是自由的障碍物。事实上恰恰相反,如果你十分完整的运行那些测试来检查你的软件的公共接口,你就可能在不改变(或者更加糟糕,破坏)原来的应用软件的前提下改变自己系统内在的执行。测试并检验你的公共接口的精确性和正确性,并且让自己随意改变一些代码的内在工作来确保你的软件是正确而且没有bug(错误)。
在讨论更多关于测试的好处之前,先让我们看一个示例。这本书里面所有的测试实例都使用了PHP测试框架——SimpleTest 。这个测试框架可以在 http://simpletest.org 获取到。
考虑下面的代码
// PHP4
// the subject code
define(‘TAX_RATE', 0.07);
function calculate_sales_tax($amount) {
round($amount * TAX_RATE,2);
}
// include test library
require_once ‘simpletest/unit_tester.php';
require_once ‘simpletest/reporter.php';
// the test
class TestingTestCase extends UnitTestCase {
function TestingTestCase($name='') {
$this->UnitTestCase($name);
}
function TestSalesTax() {
$this->assertEqual(7, calculate_sales_tax(100));
}
}
// run the test
$test = new TestingTestCase(‘Testing Unit Test');
$test->run(new HtmlReporter());
上面的代码首先定义了一个常量——TAX_RATE,和一个计算销售税的函数。接着,代码包含了使用SimpleTest框架的必备组件:单体测试本身和一个用来显示测试结果的“reporter”模块。
类TestingTestCase继承于SimpleTest框架的UnitTestCase类。通过扩展UnitTestCase,类TestingTestCase里面所有使用Test开头的方法都将被认为是测试实例——创造条件来调试你的代码并断言结果。
TestingTestCase定义了一个测试,TestSalesTax(),它包含了一个断言函数AssertEqual()。如果它的前两个输入参数是相等的,它将返回true,否则返回false。(如果你想显示assertEqual()失败的信息,你可以传入三个参数就像这样$this->assertEqual(7,calculate_sales_tax(100), “The sales tax calculation failed”))。
代码的最后两行创建了这个测试实例的实体并且使用一个HtmlReporter运行了它。你可以访问这个web页面来运行这个简单的测试。
运行这个测试将显示测试名称,失败断言的详细情况和一个总结条。(绿色的意味着成功(所有的断言都通过了),而红色的暗示着失败(至少有一个断言没有通过))
(assertion(断言)在软件开发中是一种常用的调试方式,很多开发语言中都支持这种机制。在实现中,assertion就是在程序中的一条语句,它对一个boolean表达式进行检查,一个正确程序必须保证这个boolean表达式的值为true;如果该值为false,说明程序已经处于不正确的状态下,系统将给出警告或退出。一般来说,assertion用于保证程序最基本、关键的正确性。assertion检查通常在开发和测试时开启。为了提高性能,在软件发布后,assertion检查通常是关闭的。)
注:(assertion(断言)在软件开发中是一种常用的调试方式,很多开发语言中都支持这种机制。在实现中,assertion就是在程序中的一条语句,它对一个boolean表达式进行检查,一个正确程序必须保证这个boolean表达式的值为true;如果该值为false,说明程序已经处于不正确的状态下,系统将给出警告或退出。一般来说,assertion用于保证程序最基本、关键的正确性。assertion检查通常在开发和测试时开启。为了提高性能,在软件发布后,assertion检查通常是关闭的。)
上面的代码有一个(有意的)错误,所以运行是不能通过了,显示结果如下:
Calculate_sales_tax()这么一个简单的才一行的函数哪里出错了呢?你可能已经注意到这个函数没有返回结果。下面是正确的函数:
function calculate_sales_tax($amount) {
return round($amount * TAX_RATE,2);
}
修改后运行,测试通过。
但是一个简单的测试并不能保证代码是稳定的。比如,你把calculate_sales_tax()改成 function calculate_sales_tax($amount) { return 7; },代码也会通过测试,但只有当1美元等价于100的时候才是正确的。你可以自己增加一些额外的测试方法来测试其他的静态值。
function TestSomeMoreSalesTax() {
$this->assertEqual(3.5, calculate_sales_tax(50));
}
或者改变函数TestSalesTax()来验证第二个(和第三个,等等)值,如下所示
function TestSalesTax() {
$this->assertEqual(7, calculate_sales_tax(100));
$this->assertEqual(3.5, calculate_sales_tax(50));
}
到目前为止还有一种更好的方法,就是新增加一个测试:选择随即值来测试你的代码。具体如下:
function TestRandomValuesSalesTax() {
$amount = rand(500,1000);
$this->assertTrue(defined(‘TAX_RATE'));
$tax = round($amount*TAX_RATE*100)/100;
$this->assertEqual($tax, calculate_sales_tax($amount));
}
TestRandomValuesSalesTax()引入了方法assertTrue(),如果传入的第一个变量等于于布尔真则assertTrue()通过。(和方法assertEqual()一样,方法assertTrue()在接受一个可选择性的、额外的后将返回一个失败的信息)。所以TestRandomValuesSalesTax()首先认为常量TAX_RATE已经定义了,然后使用这个常量来计算随机选择的的数量的税收。
但是TestRandomValuesSalesTax()也存在一个问题:它很大程度的依赖于方法calculate_sales_tax()。测试是应该和特殊的实现细节无关的。一个更好的测试应该只建立一个合理的分界线。接下来的这个测试假定销售税永远不会超过20%。
function TestRandomValuesSalesTax() {
$amount = rand(500,1000);
$this->assertTrue(calculate_sales_tax($amount)}
确保你的代码正常工作是测试的首要的目的,但是在测试你的代码时候,你应该认识到除此之外还有一些额外的,相对次要的目的:
- 测试让你书写容易测试的代码。这使得代码松散耦合,复杂设计,而且具有很好的模块性。
- 测试能让你清晰的了解运行代码的期望结果,让你从一开始就注重于模块的设计和分析。通过测试,也会让你考虑所有可能的输入和相应的输出结果。
- 测试能很快速的了解编码的目的。换句话说,测试事例扮演着“实例”和“文档”的功能,准确的展示着如何构建一个类,方法等。在这本书中,我有时候通过一个测试事例来演示代码的期望功能。通过读取一个测试方法的声明,你可以清楚的了解代码是如何运行的。一个测试实例定义在代码在明确惯用法下的运行情况。
最后,如果你的测试集——测试实例的集合——是非常彻底的,而且当所有的测试都通过的时候,你可以说你的代码是完备的。有趣的是,这个观点也恰好是Test Driven Development(测试驱动开发)的特征之一。
Test Driven Development(TDD)也被认为是Test First Coding(编码前测试)。Test First Coding是一种把测试更提前一步的方法:在你写任何代码之前先写好测试。你可以从http://xprogramming.com/xpmag/testFirstGuidelines.htm下载到一份很好的,简洁的关于TDD的摘要文章,同时下载到一本很好的关于策略的入门书——Kent Beck著作的《Test Driven Development:By Example》(这本书的例子都是用JAVA开发的,但其中代码的可读性是很好的,而且对主题的介绍和说明都做的很好的)。
注:敏捷开发(Agile Development)
最近,单体测试——特别是测绘驱动开发——已经和敏捷开发方法学紧密的联系起来了,比如说极限编程(XP)。极限编程的焦点关注于快速的反复的发步功能性的代码给客户,并把变化的客户需求做为开发过程中的必备部分。下面是一些关于学习敏捷编程的在线资源:
函数性测试
这本书里面的大部分测试例子都是用来测试面对对象的代码,但是所有形式的编程都可以从中得到收获的。单体测试框架,比如说PHPUnits和SimpleTest,也都能很容易的用来测试功能函数的。例如上面的SimpleTest例子,它就是用来测试calculate_sales_tax()函数的。世界各地的程序员们:把单体测试用例放到你的函数库里面吧!
我希望经过上面的讨论后,你也会被带动起来——“测试引导”(Test Infected)!(这个术语,原创于Erich Gamma,详细情况请见文章http://junit.sourceforge.net/doc/testinfected/testing.htm),就象Gamma所写的那样,刚开始你可能会感到测试是很繁琐的,但是当你为你的程序搭建好一个广阔的测试集后,你将你的代码更加自信!

熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

記事本++7.3.1
好用且免費的程式碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
強大的PHP整合開發環境

Dreamweaver CS6
視覺化網頁開發工具

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

PHP 8.4 帶來了多項新功能、安全性改進和效能改進,同時棄用和刪除了大量功能。 本指南介紹如何在 Ubuntu、Debian 或其衍生版本上安裝 PHP 8.4 或升級到 PHP 8.4

Visual Studio Code,也稱為 VS Code,是一個免費的原始碼編輯器 - 或整合開發環境 (IDE) - 可用於所有主要作業系統。 VS Code 擁有大量針對多種程式語言的擴展,可以輕鬆編寫

JWT是一種基於JSON的開放標準,用於在各方之間安全地傳輸信息,主要用於身份驗證和信息交換。 1.JWT由Header、Payload和Signature三部分組成。 2.JWT的工作原理包括生成JWT、驗證JWT和解析Payload三個步驟。 3.在PHP中使用JWT進行身份驗證時,可以生成和驗證JWT,並在高級用法中包含用戶角色和權限信息。 4.常見錯誤包括簽名驗證失敗、令牌過期和Payload過大,調試技巧包括使用調試工具和日誌記錄。 5.性能優化和最佳實踐包括使用合適的簽名算法、合理設置有效期、

字符串是由字符組成的序列,包括字母、數字和符號。本教程將學習如何使用不同的方法在PHP中計算給定字符串中元音的數量。英語中的元音是a、e、i、o、u,它們可以是大寫或小寫。 什麼是元音? 元音是代表特定語音的字母字符。英語中共有五個元音,包括大寫和小寫: a, e, i, o, u 示例 1 輸入:字符串 = "Tutorialspoint" 輸出:6 解釋 字符串 "Tutorialspoint" 中的元音是 u、o、i、a、o、i。總共有 6 個元

靜態綁定(static::)在PHP中實現晚期靜態綁定(LSB),允許在靜態上下文中引用調用類而非定義類。 1)解析過程在運行時進行,2)在繼承關係中向上查找調用類,3)可能帶來性能開銷。

本教程演示瞭如何使用PHP有效地處理XML文檔。 XML(可擴展的標記語言)是一種用於人類可讀性和機器解析的多功能文本標記語言。它通常用於數據存儲

PHP的魔法方法有哪些? PHP的魔法方法包括:1.\_\_construct,用於初始化對象;2.\_\_destruct,用於清理資源;3.\_\_call,處理不存在的方法調用;4.\_\_get,實現動態屬性訪問;5.\_\_set,實現動態屬性設置。這些方法在特定情況下自動調用,提升代碼的靈活性和效率。
