PHP 代码简洁之道 ( PHP Clean Code)(第二部分)
php 代码简洁之道 ( php clean code)(第一部分)
使用默认参数而不是使用短路运算或者是条件判断
不好的做法:
这是不太好的因为 $breweryname
可以是 null
.
function createmicrobrewery($breweryname = 'hipster brew co.'): void
{
// ...
}
还算可以的做法:
这个做法比上面的更加容易理解,但是它需要很好的去控制变量的值.
function createmicrobrewery($name = null): void
{
$breweryname = $name ?: 'hipster brew co.';
// ...
}
好的做法:
你可以使用 类型提示 而且可以保证 $breweryname
不会为空 null
.
function createmicrobrewery(string $breweryname = 'hipster brew co.'): void
{
// ...
}
}
对比
使用 相等运算符
不好的做法:
$a = '42';
$b = 42;
使用简单的相等运算符会把字符串类型转换成数字类型
if( $a != $b ) {
//这个条件表达式总是会通过
}
表达式 $a != $b 会返回 false 但实际上它应该是 true !
字符串类型 '42' 是不同于数字类型的 42
好的做法:
使用全等运算符会对比类型和值
if( $a !== $b ) {
//这个条件是通过的
}
表达式 $a !== $b 会返回 true。
函数
函数参数(2 个或更少)
限制函数参数个数极其重要
这样测试你的函数容易点。有超过 3 个可选参数会导致一个爆炸式组合增长,你会有成吨独立参数情形要测试。
无参数是理想情况。1 个或 2 个都可以,最好避免 3 个。
再多就需要加固了。通常如果你的函数有超过两个参数,说明他要处理的事太多了。 如果必须要传入很多数据,建议封装一个高级别对象作为参数。
不友好的:
function createmenu(string $title, string $body, string $buttontext, bool $cancellable): void
{
// ...
}
友好的:
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): void
{
// ...
}
函数应该只做一件事情
这是迄今为止软件工程最重要的原则。函数做了超过一件事情时,它们将变得难以编写、测试、推导。 而函数只做一件事情时,重构起来则非常简单,同时代码阅读起来也非常清晰。掌握了这个原则,你就会领先许多其他的开发者。
不好的:
function emailclients(array $clients): void
{
foreach ($clients as $client) {
$clientrecord = $db->find($client);
if ($clientrecord->isactive()) {
email($client);
}
}
}
好的:
function emailclients(array $clients): void
{
$activeclients = activeclients($clients);
array_walk($activeclients, 'email');
}
function activeclients(array $clients): array
{
return array_filter($clients, 'isclientactive');
}
function isclientactive(int $client): bool
{
$clientrecord = $db->find($client);
return $clientrecord->isactive();
}
函数的名称要说清楚它做什么 不好的例子:
class email
{
//...
public function handle(): void
{
mail($this->to, $this->subject, $this->body);
}
}
$message = new email(...);
// what is this? a handle for the message? are we writing to a file now?
$message->handle()
;
很好的例子:
class email
{
//...
public function send(): void
{
mail($this->to, $this->subject, $this->body);
}
}
$message = new email(...);
// clear and obvious
$message->send();
函数只能是一个抽象级别
当你有多个抽象层次时,你的函数功能通常是做太多了。 分割函数功能使得重用性和测试更加容易。.
不好:
function parsebetterjsalternative(string $code): void
{
$regexes = [
// ...
];
$statements = explode(' ', $code);
$tokens = [];
foreach ($regexes as $regex) {
foreach ($statements as $statement) {
// ...
}
}
$ast = [];
foreach ($tokens as $token) {
// lex...
}
foreach ($ast as $node) {
// parse...
}
}
同样不是很好:
我们已经完成了一些功能,但是 parsebetterjsalternative()
功能仍然非常复杂,测试起来也比较麻烦。
function tokenize(string $code): array
{
$regexes = [
// ...
];
$statements = explode(' ', $code);
$tokens = [];
foreach ($regexes as $regex) {
foreach ($statements as $statement) {
$tokens[] = /* ... */;
}
}
return $tokens;
}
function lexer(array $tokens): array
{
$ast = [];
foreach ($tokens as $token) {
$ast[] = /* ... */;
}
return $ast;
}
function parsebetterjsalternative(string $code): void
{
$tokens = tokenize($code);
$ast = lexer($tokens);
foreach ($ast as $node) {
// parse...
}
}
很好的:
最好的解决方案是取出 parsebetterjsalternative()
函数的依赖关系.
class tokenizer
{
public function tokenize(string $code): array
{
$regexes = [
// ...
];
$statements = explode(' ', $code);
$tokens = [];
foreach ($regexes as $regex) {
foreach ($statements as $statement) {
$tokens[] = /* ... */;
}
}
return $tokens;
}
}
class lexer
{
public function lexify(array $tokens): array
{
$ast = [];
foreach ($tokens as $token) {
$ast[] = /* ... */;
}
return $ast;
}
}
class betterjsalternative
{
private $tokenizer;
private $lexer;
public function __construct(tokenizer $tokenizer, lexer $lexer)
{
$this->tokenizer = $tokenizer;
$this->lexer = $lexer;
}
public function parse(string $code): void
{
$tokens = $this->tokenizer->tokenize($code);
$ast = $this->lexer->lexify($tokens);
foreach ($ast as $node) {
// parse...
}
}
}
更多学习内容请访问:
腾讯t3-t4标准精品php架构师教程目录大全,只要你看完保证薪资上升一个台阶(持续更新)