介绍
Robert C.Martin’s 的 软件工程师准则 Clean Code 同样适用于 PHP。它并不是一个编码风格指南,它指导我们用 PHP 写出具有可读性,可复用性且可分解的代码。
并非所有的准则都必须严格遵守,甚至一些已经成为普遍的约定。这仅仅作为指导方针,其中许多都是 Clean Code 作者们多年来的经验。
尽管许多开发者依旧使用 PHP 5 版本,但是这篇文章中绝大多数例子都是只能在 PHP 7.1 + 版本下运行。
变量
使用有意义的且可读的变量名
不友好的:
1 | $ymdstr = $moment->format( 'y-m-d' ); |
友好的:
1 | $currentDate = $moment->format( 'y-m-d' ); |
对同类型的变量使用相同的词汇
不友好的:
1 2 3 4 | getUserInfo(); getUserData(); getUserRecord(); getUserProfile(); |
友好的:
1 | getUser(); |
使用可搜索的名称(第一部分)
我们阅读的代码超过我们写的代码。所以我们写出的代码需要具备可读性、可搜索性,这一点非常重要。要我们去理解程序中没有名字的变量是非常头疼的。让你的变量可搜索吧!
不具备可读性的代码:
1 2 | // 见鬼的 448 是什么意思? $result = $serializer->serialize($data, 448); |
具备可读性的:
1 | $json = $serializer->serialize($data, JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); |
使用可搜索的名称(第二部分)
不好的:
1 2 3 4 | // 见鬼的 4 又是什么意思? if ($user->access & 4) { // ... } |
好的方式:
1 2 3 4 5 6 7 8 9 10 11 | class User { const ACCESS_READ = 1; const ACCESS_CREATE = 2; const ACCESS_UPDATE = 4; const ACCESS_DELETE = 8; } if ($user->access & User::ACCESS_UPDATE) { // do edit ... } |
使用解释性变量
不好:
1 2 3 4 5 | $address = 'One Infinite Loop, Cupertino 95014' ; $cityZipCodeRegex = '/^[^,]+,\s*(.+?)\s*(\d{5})$/' ; preg_match($cityZipCodeRegex, $address, $matches); saveCityZipCode($matches[1], $matches[2]); |
一般:
这个好点,但我们仍严重依赖正则表达式。
1 2 3 4 5 6 | $address = 'One Infinite Loop, Cupertino 95014' ; $cityZipCodeRegex = '/^[^,]+,\s*(.+?)\s*(\d{5})$/' ; preg_match($cityZipCodeRegex, $address, $matches); [, $city, $zipCode] = $matches; saveCityZipCode($city, $zipCode); |
很棒:
通过命名子模式减少对正则表达式的依赖。
1 2 3 4 5 | $address = 'One Infinite Loop, Cupertino 95014' ; $cityZipCodeRegex = '/^[^,]+,\s*(?<city>.+?)\s*(?<zipCode>\d{5})$/' ; preg_match($cityZipCodeRegex, $address, $matches); saveCityZipCode($matches[ 'city' ], $matches[ 'zipCode' ]); |
避免嵌套太深和提前返回 (第一部分)
使用太多 if else
表达式会导致代码难以理解。
明确优于隐式。
不好:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | function isShopOpen($day): bool { if ($day) { if (is_string($day)) { $day = strtolower($day); if ($day === 'friday' ) { return true ; } elseif ($day === 'saturday' ) { return true ; } elseif ($day === 'sunday' ) { return true ; } else { return false ; } } else { return false ; } } else { return false ; } } |
很棒:
1 2 3 4 5 6 7 8 9 10 11 12 | function isShopOpen( string $day): bool { if (empty($day)) { return false ; } $openingDays = [ 'friday' , 'saturday' , 'sunday' ]; return in_array(strtolower($day), $openingDays, true ); } |
避免嵌套太深和提前返回 (第二部分)
不好:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | function fibonacci( int $n) { if ($n < 50) { if ($n !== 0) { if ($n !== 1) { return fibonacci($n - 1) + fibonacci($n - 2); } else { return 1; } } else { return 0; } } else { return 'Not supported' ; } } |
很棒:
1 2 3 4 5 6 7 8 9 10 11 12 | function fibonacci( int $n): int { if ($n === 0 || $n === 1) { return $n; } if ($n > 50) { throw new \Exception( 'Not supported' ); } return fibonacci($n - 1) + fibonacci($n - 2); } |
避免心理映射
不要迫使你的代码阅读者翻译变量的意义。
明确优于隐式。
不好:
1 2 3 4 5 6 7 8 9 10 11 12 | $l = [ 'Austin' , 'New York' , 'San Francisco' ]; for ($i = 0; $i < count($l); $i++) { $li = $l[$i]; doStuff(); doSomeOtherStuff(); // ... // ... // ... // Wait, what is `$li` for again? dispatch($li); } |
很棒:
1 2 3 4 5 6 7 8 9 10 | $locations = [ 'Austin' , 'New York' , 'San Francisco' ]; foreach ($locations as $location) { doStuff(); doSomeOtherStuff(); // ... // ... // ... dispatch($location); } |
不要增加不需要的上下文
如果类名或对象名告诉你某些东西后,请不要在变量名中重复。
小坏坏:
1 2 3 4 5 6 7 8 | class Car { public $carMake; public $carModel; public $carColor; //... } |
好的方式:
1 2 3 4 5 6 7 8 | class Car { public $make; public $model; public $color; //... } |
本文来自投稿,不代表程序员编程网立场,如若转载,请注明出处:http://www.cxybcw.com/189229.html