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->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...

}

}

}

更多学习内容请访问:

总结

如果觉得编程之家网站内容还不错,欢迎将编程之家网站推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值