PHP整洁之道
Bad:
$ymdstr = $moment->format('y-m-d');
Good:
$currentDate = $moment->format('y-m-d');
Bad:
getUserInfo();
getClientData();
getCustomerRecord();
Good:
getUser();
Bad:
// What the heck is 86400 for?
addExpireAt();
Good:
// Declare them as capitalized `const` globals.
interface DateGlobal {
const SECONDS_IN_A_DAY = ;
} addExpireAt(DateGlobal::SECONDS_IN_A_DAY);
Bad:
$address = 'One Infinite Loop, Cupertino 95014';
$cityZipCodeRegex = '/^[^,\\]+[,\\\s]+(.+?)\s*(\d{5})?$/';
preg_match($cityZipCodeRegex, $address, $matches);
saveCityZipCode($matches[], $matches[]);
Good:
$address = 'One Infinite Loop, Cupertino 95014';
$cityZipCodeRegex = '/^[^,\\]+[,\\\s]+(.+?)\s*(\d{5})?$/';
preg_match($cityZipCodeRegex, $address, $matches);
list(, $city, $zipCode) = $matchers;
saveCityZipCode($city, $zipCode);
Bad:
$l = ['Austin', 'New York', 'San Francisco'];
foreach($i=; $i<count($l); $i++) {
oStuff();
doSomeOtherStuff();
// ...
// ...
// ...
// 等等`$l` 又代表什么?
dispatch($l);
}
Good:
$locations = ['Austin', 'New York', 'San Francisco'];
foreach($i=; $i<count($locations); $i++) {
$location = $locations[$i]; doStuff();
doSomeOtherStuff();
// ...
// ...
// ...
dispatch($location);
});
Bad:
$car = [
'carMake' => 'Honda',
'carModel' => 'Accord',
'carColor' => 'Blue',
]; function paintCar(&$car) {
$car['carColor'] = 'Red';
}
Good:
$car = [
'make' => 'Honda',
'model' => 'Accord',
'color' => 'Blue',
]; function paintCar(&$car) {
$car['color'] = 'Red';
}
Bad:
function createMicrobrewery($name = null) {
$breweryName = $name ?: 'Hipster Brew Co.';
// ...
}
Good:
function createMicrobrewery($breweryName = 'Hipster Brew Co.') {
// ...
}
Bad:
function createMenu($title, $body, $buttonText, $cancellable) {
// ...
}
Good:
class menuConfig() {
public $title;
public $body;
public $buttonText;
public $cancellable = false;
} $config = new MenuConfig();
$config->title = 'Foo';
$config->body = 'Bar';
$config->buttonText = 'Baz';
$config->cancellable = true; function createMenu(MenuConfig $config) {
// ...
}
Bad:
function emailClients($clients) {
foreach ($clients as $client) {
$clientRecord = $db->find($client);
if($clientRecord->isActive()) {
email($client);
}
}
}
Good:
function emailClients($clients) {
$activeClients = activeClients($clients);
array_walk($activeClients, 'email');
} function activeClients($clients) {
return array_filter($clients, 'isClientActive');
} function isClientActive($client) {
$clientRecord = $db->find($client);
return $clientRecord->isActive();
}
Bad:
function addToDate($date, $month) {
// ...
} $date = new \DateTime(); // It's hard to to tell from the function name what is added
addToDate($date, );
Good:
function addMonthToDate($month, $date) {
// ...
} $date = new \DateTime();
addMonthToDate(, $date);
Bad:
function parseBetterJSAlternative($code) {
$regexes = [
// ...
]; $statements = split(' ', $code);
$tokens = [];
foreach($regexes as $regex) {
foreach($statements as $statement) {
// ...
}
} $ast = [];
foreach($tokens as $token) {
// lex...
} foreach($ast as $node) {
// parse...
}
}
Good:
function tokenize($code) {
$regexes = [
// ...
]; $statements = split(' ', $code);
$tokens = [];
foreach($regexes as $regex) {
foreach($statements as $statement) {
$tokens[] = /* ... */;
});
}); return tokens;
} function lexer($tokens) {
$ast = [];
foreach($tokens as $token) {
$ast[] = /* ... */;
}); return ast;
} function parseBetterJSAlternative($code) {
$tokens = tokenize($code);
$ast = lexer($tokens);
foreach($ast as $node) {
// parse...
});
}
Bad:
function showDeveloperList($developers) {
foreach($developers as $developer) {
$expectedSalary = $developer->calculateExpectedSalary();
$experience = $developer->getExperience();
$githubLink = $developer->getGithubLink();
$data = [
$expectedSalary,
$experience,
$githubLink
]; render($data);
}
} function showManagerList($managers) {
foreach($managers as $manager) {
$expectedSalary = $manager->calculateExpectedSalary();
$experience = $manager->getExperience();
$githubLink = $manager->getGithubLink();
$data = [
$expectedSalary,
$experience,
$githubLink
]; render($data);
}
}
Good:
function showList($employees) {
foreach($employees as $employe) {
$expectedSalary = $employe->calculateExpectedSalary();
$experience = $employe->getExperience();
$githubLink = $employe->getGithubLink();
$data = [
$expectedSalary,
$experience,
$githubLink
]; render($data);
}
}
Bad:
$menuConfig = [
'title' => null,
'body' => 'Bar',
'buttonText' => null,
'cancellable' => true,
]; function createMenu(&$config) {
$config['title'] = $config['title'] ?: 'Foo';
$config['body'] = $config['body'] ?: 'Bar';
$config['buttonText'] = $config['buttonText'] ?: 'Baz';
$config['cancellable'] = $config['cancellable'] ?: true;
} createMenu($menuConfig);
Good:
$menuConfig = [
'title' => 'Order',
// User did not include 'body' key
'buttonText' => 'Send',
'cancellable' => true,
]; function createMenu(&$config) {
$config = array_merge([
'title' => 'Foo',
'body' => 'Bar',
'buttonText' => 'Baz',
'cancellable' => true,
], $config); // config now equals: {title: "Order", body: "Bar", buttonText: "Send", cancellable: true}
// ...
} createMenu($menuConfig);
Bad:
function createFile(name, temp = false) {
if (temp) {
touch('./temp/'.$name);
} else {
touch($name);
}
}
Good:
function createFile($name) {
touch(name);
} function createTempFile($name) {
touch('./temp/'.$name);
}
Bad:
// Global variable referenced by following function.
// If we had another function that used this name, now it'd be an array and it could break it.
$name = 'Ryan McDermott'; function splitIntoFirstAndLastName() {
$name = preg_split('/ /', $name);
} splitIntoFirstAndLastName(); var_dump($name); // ['Ryan', 'McDermott'];
Good:
$name = 'Ryan McDermott'; function splitIntoFirstAndLastName($name) {
return preg_split('/ /', $name);
} $name = 'Ryan McDermott';
$newName = splitIntoFirstAndLastName(name); var_export($name); // 'Ryan McDermott';
var_export($newName); // ['Ryan', 'McDermott'];
Bad:
function config() {
return [
'foo': 'bar',
]
};
Good:
class Configuration {
private static $instance;
private function __construct($configuration) {/* */}
public static function getInstance() {
if(self::$instance === null) {
self::$instance = new Configuration();
}
return self::$instance;
}
public function get($key) {/* */}
public function getAll() {/* */}
} $singleton = Configuration::getInstance();
Bad:
if ($fsm->state === 'fetching' && is_empty($listNode)) {
// ...
}
Good:
function shouldShowSpinner($fsm, $listNode) {
return $fsm->state === 'fetching' && is_empty(listNode);
} if (shouldShowSpinner($fsmInstance, $listNodeInstance)) {
// ...
}
Bad:
function isDOMNodeNotPresent($node) {
// ...
} if (!isDOMNodeNotPresent($node)) {
// ...
}
Good:
function isDOMNodePresent($node) {
// ...
} if (isDOMNodePresent($node)) {
// ...
}
Bad:
class Airplane {
// ...
public function getCruisingAltitude() {
switch (this.type) {
case '':
return $this->getMaxAltitude() - $this->getPassengerCount();
case 'Air Force One':
return $this->getMaxAltitude();
case 'Cessna':
return $this->getMaxAltitude() - $this->getFuelExpenditure();
}
}
}
Good:
class Airplane {
// ...
} class Boeing777 extends Airplane {
// ...
public function getCruisingAltitude() {
return $this->getMaxAltitude() - $this->getPassengerCount();
}
} class AirForceOne extends Airplane {
// ...
public function getCruisingAltitude() {
return $this->getMaxAltitude();
}
} class Cessna extends Airplane {
// ...
public function getCruisingAltitude() {
return $this->getMaxAltitude() - $this->getFuelExpenditure();
}
}
Bad:
function travelToTexas($vehicle) {
if ($vehicle instanceof Bicycle) {
$vehicle->peddle($this->currentLocation, new Location('texas'));
} else if ($vehicle instanceof Car) {
$vehicle->drive($this->currentLocation, new Location('texas'));
}
}
Good:
function travelToTexas($vehicle) {
$vehicle->move($this->currentLocation, new Location('texas'));
}
Bad:
function combine($val1, $val2) {
if (is_numeric($val1) && is_numeric(val2)) {
return val1 + val2;
} throw new \Exception('Must be of type Number');
}
Good:
function combine(int $val1, int $val2) {
return $val1 + $val2;
}
Bad:
function oldRequestModule($url) {
// ...
} function newRequestModule($url) {
// ...
} $req = new newRequestModule();
inventoryTracker('apples', $req, 'www.inventory-awesome.io');
Good:
function newRequestModule($url) {
// ...
} $req = new newRequestModule();
inventoryTracker('apples', $req, 'www.inventory-awesome.io');
PHP整洁之道的更多相关文章
- <读书笔记> 代码整洁之道
概述 1.本文档的内容主要来源于书籍<代码整洁之道>作者Robert C.Martin,属于读书笔记. 2.软件质量,不仅依赖于架构和项目管理,而且与代码质量紧密相关,本书提出一 ...
- <代码整洁之道>、<java与模式>、<head first设计模式>读书笔记集合
一.前言 几个月前的看书笔记 ...
- 免费电子书:C#代码整洁之道
(此文章同时发表在本人微信公众号"dotNET每日精华文章",欢迎右边二维码来关注.) 题记:<Clean Code(代码整洁之道)>是一本经典的著作,那么对于编写整洁 ...
- 2015年第11本:代码整洁之道Clean Code
前一段时间一直在看英文小说,在读到<Before I fall>这本书时,读了40%多实在看不下去了,受不了美国人啰啰嗦嗦的写作风格,还是读IT专业书吧. 从5月9日开始看<代码整洁 ...
- android开发系列之代码整洁之道
说起代码整洁之道,想必大家想到更多的是那本经典重构书籍.没错,记得当时自己读那本书的时候,一边结合项目实战,一边结合书中的讲解,确实学到了很多东西,对我自己的编码风格影响极深.随着时间的流逝,书中很多 ...
- 读<<代码整洁之道>>的感想
花去了近一周的时间浏览一下这本书.总体感觉这本书写得不错. 我发现自己以前写的代码时多么的糟糕.有很多改进之处... 同时我也发现写出优秀的代码不易.优秀的代码不仅仅易读,并且易修改,易维护,程序易维 ...
- 如何写出如散文般的代码――《代码整洁之道》读书笔记(Ch1-Ch3)
不知道有多少人像我一样,程序出现问题时添加函数添加变量解决,变量名用a,b,c等"简单"的字母来表示.不知道有多少人像我一样,看完自己的代码,心里暗骂"什么玩意儿!&qu ...
- 《代码整洁之道》(Clean Code)- 读书笔记
一.关于Bob大叔的Clean Code <代码整洁之道>主要讲述了一系列行之有效的整洁代码操作实践.软件质量,不但依赖于架构及项目管理,而且与代码质量紧密相关.这一点,无论是敏捷开发流派 ...
- Programming好文解读系列(—)——代码整洁之道
注:初入职场,作为一个程序员,要融入项目组的编程风格,渐渐地觉得系统地研究下如何写出整洁而高效的代码还是很有必要的.与在学校时写代码的情况不同,实现某个功能是不难的,需要下功夫的地方在于如何做一些防御 ...
- Docker -- 系统整洁之道 -- 1
在上文Docker – 系统整洁之道 – 0中已经对Docker是什么,安装Docker以及怎么运行一个简单的容器有了初步了解,这篇文章介绍Docker的一些命令和Docker镜像的使用及操作. 一些 ...
随机推荐
- Php导出百万数据的优化
导出数据量很大的情况下,生成excel的内存需求非常庞大,服务器吃不消,这个时候考虑生成csv来解决问题,cvs读写性能比excel高.测试表student 数据(大家可以脚本插入300多万测数据.这 ...
- PHP Composer 依赖管理的用法
1:下载 1.1:方法一: 通过PHP来安装 cd G:\web\es6 curl -sS https://getcomposer.org/installer | php #这个命令会下载compos ...
- java Calendar的学习分享
前言: 在我们的日常生活中,常常能看见时间.如:在我们的手机里,在一些网站上也能随处看到时间.那我们在项目的开发中,也常常涉及到时间的处理,对于我们经常会遇到和处理的问题.Java中专门为我们处理时间 ...
- 作为开发人员,这四类Code Review方法你都知道吗?
本文翻译自:https://dzone.com/articles/4-types-of-code-reviews-any-professional-developer 转载请注明出处:葡萄城官网,葡萄 ...
- 加载loading对话框的功能(不退出沉浸式效果)
上一篇基于修改系统源码的前提下,实现了完全的沉浸式体验效果.可参考这篇 戳这 一.自定义Dialog 在沉浸式效果下,当界面弹出对话框时,对话框将获取到焦点,这将导致界面退出沉浸式效果,那么是不是能通 ...
- java基础中this,super
this是自身的一个对象,代表对象本身,可以理解为:指向对象本身的一个指针. super可以理解为是指向自己超(父)类对象的一个指针,而这个超类指的是离自己最近的一个父类. this的用法就不累赘的说 ...
- 版本控制工具(SVN/Git)介绍
文章大纲 一.SVN介绍二.Git介绍三.IDEA使用SVN和Git四.总结五.参考文章 一.SVN介绍 1. SVN服务器搭建和使用 首先来下载和搭建SVN服务器,下载地址如下: http:// ...
- Java 集合系列(二)—— ArrayList
ArrayList ArrayList 是通过一个数组来实现的,因此它是在连续的存储位置存放对象的引用,只不过它比 Array 更智能,能够根据集合长度进行自动扩容. 假设让我们来实现一个简单的能够自 ...
- Windows程序设计:格式化对话框的设计
刚开始学习Windows程序设计,磕磕碰碰,先做个小笔记缓缓神经,主要是将MessageBox这个Windows API函数的. MessageBox函数是许多人刚开始学习Windows程序设计或者是 ...
- .NET Core跨平台部署
目录 .NET Core跨平台部署 1. Windows-IIS 1.1 安装.NET Core Windows Server Hosting 1.2 配置应用程序池 1.3 使用发布文件 2 Lin ...